diff options
| author | 2023-05-25 01:27:59 +0000 | |
|---|---|---|
| committer | 2023-05-25 01:27:59 +0000 | |
| commit | 2cb51370f99ddfb1cb22d1edd666e84aa1c930ef (patch) | |
| tree | 7d92aec4629a8930ecbff7319c303967e8daa945 | |
| parent | b185da2a5816887daf06e48174e45cd616a5a129 (diff) | |
| parent | 9d6123ae0c075b049f56bddf0b94fdd6e54f196c (diff) | |
Merge "Correct the pair-to-pair transition animation" into udc-dev
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());      }  |