From 0f31aa29c2ff311c1ae0c4c4cca6f5539173e8ec Mon Sep 17 00:00:00 2001 From: Jerry Chang Date: Wed, 30 Nov 2022 04:13:43 +0000 Subject: [PATCH] Consolidate leaving split screen to pip mode behavior Stop always putting another side to the bottom when a splitting task is entering pip mode. Leave it to onStageHasChildrenChanged to handle, and prevent expanding non-visible side to the top after dismissed the split screen, so flows of leaving split to pip like swipe-to-home or launching another fullscreen app won't expand another side to top unexpectedly. When swipe-to-home from a split pair, it dismisses split screen. However, it also performs fling divider to dismiss animation if one side of the split is empty due to entering pip. Which might be conflicting with each other and leaves the split layout modified with the fling animation but not preperly reset divide position. Update to make sure it always resets divide position and cancel running fling animation after split screen dismissed. Fix: 227727673 Test: atest WMShellUnitTests Test: verify entering pip from split behavior with back-key, home-key and launching another fullscreen app. Video: http://recall/-/fLARJNt42LVxc3tt86SneW/gvATxkQhdJ0APek6RwRHel http://recall/-/fLARJNt42LVxc3tt86SneW/QfHt9H0XtDNDSP3h1AA8K http://recall/-/fLARJNt42LVxc3tt86SneW/QnbdeWo2007s8ZuMf1Syn Change-Id: I2c53ed21e4766d06180e670ee21534cd622db081 --- .../wm/shell/common/split/SplitLayout.java | 23 ++++++++++++++----- .../shell/splitscreen/StageCoordinator.java | 15 +----------- .../shell/splitscreen/StageTaskListener.java | 6 ----- 3 files changed, 18 insertions(+), 26 deletions(-) diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java index ae496165028f5..45b234a6398a7 100644 --- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java +++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java @@ -122,6 +122,7 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange private int mDensity; private final boolean mDimNonImeSide; + private ValueAnimator mDividerFlingAnimator; public SplitLayout(String windowName, Context context, Configuration configuration, SplitLayoutHandler splitLayoutHandler, @@ -395,6 +396,10 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange mSplitWindowManager.release(t); mDisplayImeController.removePositionProcessor(mImePositionProcessor); mImePositionProcessor.reset(); + if (mDividerFlingAnimator != null) { + mDividerFlingAnimator.cancel(); + } + resetDividerPosition(); } public void release() { @@ -577,13 +582,18 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange CUJ_SPLIT_SCREEN_RESIZE); return; } - ValueAnimator animator = ValueAnimator + + if (mDividerFlingAnimator != null) { + mDividerFlingAnimator.cancel(); + } + + mDividerFlingAnimator = ValueAnimator .ofInt(from, to) .setDuration(duration); - animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); - animator.addUpdateListener( + mDividerFlingAnimator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN); + mDividerFlingAnimator.addUpdateListener( animation -> updateDivideBounds((int) animation.getAnimatedValue())); - animator.addListener(new AnimatorListenerAdapter() { + mDividerFlingAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationEnd(Animator animation) { if (flingFinishedCallback != null) { @@ -591,14 +601,15 @@ public final class SplitLayout implements DisplayInsetsController.OnInsetsChange } InteractionJankMonitorUtils.endTracing( CUJ_SPLIT_SCREEN_RESIZE); + mDividerFlingAnimator = null; } @Override public void onAnimationCancel(Animator animation) { - setDividePosition(to, true /* applyLayoutChange */); + mDividerFlingAnimator = null; } }); - animator.start(); + mDividerFlingAnimator.start(); } /** Switch both surface position with animation. */ 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 acb71a80ee8a0..d805a5a262ecf 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 @@ -1035,7 +1035,7 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, mIsDividerRemoteAnimating = false; mSplitLayout.getInvisibleBounds(mTempRect1); - if (childrenToTop == null) { + if (childrenToTop == null || childrenToTop.getTopVisibleChildTaskId() == INVALID_TASK_ID) { mSideStage.removeAllTasks(wct, false /* toTop */); mMainStage.deactivate(wct, false /* toTop */); wct.reorder(mRootTaskInfo.token, false /* onTop */); @@ -1294,13 +1294,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, } } - 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() { if (!mShouldUpdateRecents) { return; @@ -2063,7 +2056,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, // Update divider state after animation so that it is still around and positioned // properly for the animation itself. mSplitLayout.release(); - mSplitLayout.resetDividerPosition(); mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED; } } @@ -2339,11 +2331,6 @@ public class StageCoordinator implements SplitLayout.SplitLayoutHandler, StageCoordinator.this.onStageChildTaskStatusChanged(this, taskId, present, visible); } - @Override - public void onChildTaskEnterPip() { - StageCoordinator.this.onStageChildTaskEnterPip(); - } - @Override public void onRootTaskVanished() { reset(); 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 bcf900b99c69e..358f712f76b5c 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 @@ -18,7 +18,6 @@ package com.android.wm.shell.splitscreen; import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW; -import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED; import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED; import static android.view.RemoteAnimationTarget.MODE_OPENING; @@ -74,8 +73,6 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { void onChildTaskStatusChanged(int taskId, boolean present, boolean visible); - void onChildTaskEnterPip(); - void onRootTaskVanished(); void onNoLongerSupportMultiWindow(); @@ -257,9 +254,6 @@ class StageTaskListener implements ShellTaskOrganizer.TaskListener { // Status is managed/synchronized by the transition lifecycle. return; } - if (taskInfo.getWindowingMode() == WINDOWING_MODE_PINNED) { - mCallbacks.onChildTaskEnterPip(); - } sendStatusChanged(); } else { throw new IllegalArgumentException(this + "\n Unknown task: " + taskInfo