summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Wei Sheng Shih <wilsonshih@google.com> 2023-05-25 01:27:59 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2023-05-25 01:27:59 +0000
commit2cb51370f99ddfb1cb22d1edd666e84aa1c930ef (patch)
tree7d92aec4629a8930ecbff7319c303967e8daa945
parentb185da2a5816887daf06e48174e45cd616a5a129 (diff)
parent9d6123ae0c075b049f56bddf0b94fdd6e54f196c (diff)
Merge "Correct the pair-to-pair transition animation" into udc-dev
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java61
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java7
-rw-r--r--libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java8
-rw-r--r--libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java4
4 files changed, 74 insertions, 6 deletions
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index e0ffffffa727..256d48c5618c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -192,6 +192,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
private final SplitScreenTransitions mSplitTransitions;
private final SplitscreenEventLogger mLogger;
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 Rect mTempRect1 = new Rect();
@@ -658,6 +661,10 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
// Add task launch requests
wct.startTask(mainTaskId, mainOptions);
+ // leave recents animation by re-start pausing tasks
+ if (mPausingTasks.contains(mainTaskId)) {
+ mPausingTasks.clear();
+ }
mSplitTransitions.startEnterTransition(
TRANSIT_TO_FRONT, wct, remoteTransition, this, null, null,
TRANSIT_SPLIT_SCREEN_PAIR_OPEN, false);
@@ -1630,7 +1637,8 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
}
private void updateRecentTasksSplitPair() {
- if (!mShouldUpdateRecents) {
+ // Preventing from single task update while processing recents.
+ if (!mShouldUpdateRecents || !mPausingTasks.isEmpty()) {
return;
}
mRecentTasks.ifPresent(recentTasks -> {
@@ -2582,6 +2590,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
final TransitionInfo.Change change = info.getChanges().get(iC);
final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
if (taskInfo == null || !taskInfo.hasParentTask()) continue;
+ if (mPausingTasks.contains(taskInfo.taskId)) {
+ continue;
+ }
final @StageType int stageType = getStageType(getStageOfTask(taskInfo));
if (stageType == STAGE_TYPE_MAIN
&& (isOpeningType(change.getMode()) || change.getMode() == TRANSIT_CHANGE)) {
@@ -2654,6 +2665,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
mShowDecorImmediately = true;
mSplitLayout.flingDividerToCenter();
}
+ mPausingTasks.clear();
});
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. */
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 */);
}
+ /** 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. */
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
// split, so we can restore the divider bar.
for (int i = 0; i < finishWct.getHierarchyOps().size(); ++i) {
@@ -2840,6 +2873,27 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
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) {
final SurfaceControl leash = mSplitLayout.getDividerLeash();
if (leash == null || !leash.isValid()) {
@@ -2892,6 +2946,9 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler,
pw.println(innerPrefix + "SplitLayout");
mSplitLayout.dump(pw, childPrefix);
}
+ if (!mPausingTasks.isEmpty()) {
+ pw.println(childPrefix + "mPausingTasks=" + mPausingTasks);
+ }
}
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
index da7d18641a97..92ff5fed4584 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageTaskListener.java
@@ -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) {
wct.reparentTasks(null /* currentParent */, mRootTaskInfo.token,
CONTROLLED_WINDOWING_MODES, CONTROLLED_ACTIVITY_TYPES,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 863b5ab73a7d..64571e067a83 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -540,9 +540,12 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
mixed.mInFlightSubAnimations = 0;
mActiveTransitions.remove(mixed);
// If pair-to-pair switching, the post-recents clean-up isn't needed.
+ wct = wct != null ? wct : new WindowContainerTransaction();
if (mixed.mAnimType != MixedTransition.ANIM_TYPE_PAIR_TO_PAIR) {
- wct = wct != null ? wct : new WindowContainerTransaction();
- mSplitHandler.onRecentsInSplitAnimationFinish(wct, finishTransaction, info);
+ mSplitHandler.onRecentsInSplitAnimationFinish(wct, finishTransaction);
+ } else {
+ // notify pair-to-pair recents animation finish
+ mSplitHandler.onRecentsPairToPairAnimationFinish(wct);
}
mSplitHandler.onTransitionAnimationComplete();
finishCallback.onTransitionFinished(wct, wctCB);
@@ -552,6 +555,7 @@ public class DefaultMixedHandler implements Transitions.TransitionHandler,
final boolean handled = mixed.mLeftoversHandler.startAnimation(mixed.mTransition, info,
startTransaction, finishTransaction, finishCB);
if (!handled) {
+ mSplitHandler.onRecentsInSplitAnimationCanceled();
mActiveTransitions.remove(mixed);
}
return handled;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index 60c0e5535568..5f705d743601 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -283,7 +283,7 @@ public class SplitTransitionTests extends ShellTestCase {
// Make sure it cleans-up if recents doesn't restore
WindowContainerTransaction commitWCT = new WindowContainerTransaction();
mStageCoordinator.onRecentsInSplitAnimationFinish(commitWCT,
- mock(SurfaceControl.Transaction.class), mock(TransitionInfo.class));
+ mock(SurfaceControl.Transaction.class));
assertFalse(mStageCoordinator.isSplitScreenVisible());
}
@@ -322,7 +322,7 @@ public class SplitTransitionTests extends ShellTestCase {
mMainStage.onTaskAppeared(mMainChild, mock(SurfaceControl.class));
mSideStage.onTaskAppeared(mSideChild, mock(SurfaceControl.class));
mStageCoordinator.onRecentsInSplitAnimationFinish(restoreWCT,
- mock(SurfaceControl.Transaction.class), mock(TransitionInfo.class));
+ mock(SurfaceControl.Transaction.class));
assertTrue(mStageCoordinator.isSplitScreenVisible());
}