diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 9f1e47f15a..2f52c9d6c3 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -249,6 +249,8 @@ public abstract class AbsSwipeUpHandler, private RunningWindowAnim[] mRunningWindowAnim; // Possible second animation running at the same time as mRunningWindowAnim private Animator mParallelRunningAnim; + // Current running divider animation + private ValueAnimator mDividerAnimator; private boolean mIsMotionPaused; private boolean mHasMotionEverBeenPaused; @@ -831,8 +833,8 @@ public abstract class AbsSwipeUpHandler, // Notify when the animation starts flushOnRecentsAnimationAndLauncherBound(); - TaskViewUtils.setSplitAuxiliarySurfacesShown(mRecentsAnimationTargets.nonApps, - false /*shown*/, true /*animate*/); + // Start hiding the divider + setDividerShown(false, false /* immediate */); // Only add the callback to enable the input consumer after we actually have the controller mStateCallback.runOnceAtState(STATE_APP_CONTROLLER_RECEIVED | STATE_GESTURE_STARTED, @@ -849,8 +851,7 @@ public abstract class AbsSwipeUpHandler, mStateCallback.setStateOnUiThread(STATE_GESTURE_CANCELLED | STATE_HANDLER_INVALIDATED); if (mRecentsAnimationTargets != null) { - TaskViewUtils.setSplitAuxiliarySurfacesShown(mRecentsAnimationTargets.nonApps, - true /*shown*/, true /*animate*/); + setDividerShown(true, false /* immediate */); } // Defer clearing the controller and the targets until after we've updated the state @@ -1000,8 +1001,7 @@ public abstract class AbsSwipeUpHandler, mStateCallback.setState(STATE_RESUME_LAST_TASK); } if (mRecentsAnimationTargets != null) { - TaskViewUtils.setSplitAuxiliarySurfacesShown(mRecentsAnimationTargets.nonApps, - true /*shown*/, false /*animate*/); + setDividerShown(true, true /* immediate */); } break; } @@ -1653,8 +1653,7 @@ public abstract class AbsSwipeUpHandler, mActivityInterface.onTransitionCancelled(wasVisible, mGestureState.getEndTarget()); if (mRecentsAnimationTargets != null) { - TaskViewUtils.setSplitAuxiliarySurfacesShown(mRecentsAnimationTargets.nonApps, - true /*shown*/, false /*animate*/); + setDividerShown(true, true /* immediate */); } // Leave the pending invisible flag, as it may be used by wallpaper open animation. @@ -1920,8 +1919,7 @@ public abstract class AbsSwipeUpHandler, @Override public void onRecentsAnimationFinished(RecentsAnimationController controller) { if (!controller.getFinishTargetIsLauncher()) { - TaskViewUtils.setSplitAuxiliarySurfacesShown(mRecentsAnimationTargets.nonApps, - true /*shown*/, true /*animate*/); + setDividerShown(true, false /* immediate */); } mRecentsAnimationController = null; mRecentsAnimationTargets = null; @@ -2026,6 +2024,19 @@ public abstract class AbsSwipeUpHandler, return scaleProgress; } + private void setDividerShown(boolean shown, boolean immediate) { + if (mDividerAnimator != null) { + mDividerAnimator.cancel(); + } + mDividerAnimator = TaskViewUtils.createSplitAuxiliarySurfacesAnimator( + mRecentsAnimationTargets.nonApps, shown, (dividerAnimator) -> { + dividerAnimator.start(); + if (immediate) { + dividerAnimator.end(); + } + }); + } + /** * Used for winscope tracing, see launcher_trace.proto * @see com.android.systemui.shared.tracing.ProtoTraceable#writeToProto diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java index 5d9a537165..30e225a932 100644 --- a/quickstep/src/com/android/quickstep/TaskViewUtils.java +++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java @@ -85,6 +85,7 @@ import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat. import java.util.ArrayList; import java.util.List; +import java.util.function.Consumer; /** * Utility class for helpful methods related to {@link TaskView} objects and their tasks. @@ -538,8 +539,16 @@ public final class TaskViewUtils { nonAppTargets, depthController, pa); if (launcherClosing) { // TODO(b/182592057): differentiate between "restore split" vs "launch fullscreen app" - TaskViewUtils.setSplitAuxiliarySurfacesShown(nonAppTargets, - true /*shown*/, true /*animate*/, pa); + TaskViewUtils.createSplitAuxiliarySurfacesAnimator(nonAppTargets, true /*shown*/, + (dividerAnimator) -> { + // If split apps are launching, we want to delay showing the divider bar + // until the very end once the apps are mostly in place. This is because we + // aren't moving the divider leash in the relative position with the + // launching apps. + dividerAnimator.setStartDelay(pa.getDuration() + - SPLIT_DIVIDER_ANIM_DURATION); + pa.add(dividerAnimator); + }); } Animator childStateAnimation = null; @@ -594,16 +603,17 @@ public final class TaskViewUtils { anim.addListener(windowAnimEndListener); } - public static void setSplitAuxiliarySurfacesShown(RemoteAnimationTargetCompat[] nonApps, - boolean shown, boolean animate) { - setSplitAuxiliarySurfacesShown(nonApps, shown, animate,null); - } - - private static void setSplitAuxiliarySurfacesShown( - @NonNull RemoteAnimationTargetCompat[] nonApps, boolean shown, boolean animate, - @Nullable PendingAnimation splitLaunchAnimation) { + /** + * Creates an animation to show/hide the auxiliary surfaces (aka. divider bar), only calling + * {@param animatorHandler} if there are valid surfaces to animate. + * + * @return the animator animating the surfaces + */ + public static ValueAnimator createSplitAuxiliarySurfacesAnimator( + RemoteAnimationTargetCompat[] nonApps, boolean shown, + Consumer animatorHandler) { if (nonApps == null || nonApps.length == 0) { - return; + return null; } SurfaceControl.Transaction t = new SurfaceControl.Transaction(); @@ -618,20 +628,7 @@ public final class TaskViewUtils { } } if (!hasSurfaceToAnimate) { - return; - } - - if (!animate) { - for (SurfaceControl leash : auxiliarySurfaces) { - t.setAlpha(leash, shown ? 1 : 0); - if (shown) { - t.show(leash); - } else { - t.hide(leash); - } - } - t.apply(); - return; + return null; } ValueAnimator dockFadeAnimator = ValueAnimator.ofFloat(0f, 1f); @@ -668,15 +665,7 @@ public final class TaskViewUtils { } }); dockFadeAnimator.setDuration(SPLIT_DIVIDER_ANIM_DURATION); - if (splitLaunchAnimation != null) { - // If split apps are launching, we want to delay showing the divider bar until the very - // end once the apps are mostly in place. This is because we aren't moving the divider - // leash in the relative position with the launching apps. - dockFadeAnimator.setStartDelay( - splitLaunchAnimation.getDuration() - SPLIT_DIVIDER_ANIM_DURATION); - splitLaunchAnimation.add(dockFadeAnimator); - } else { - dockFadeAnimator.start(); - } + animatorHandler.accept(dockFadeAnimator); + return dockFadeAnimator; } } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 8e772f680a..7218cd73e1 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -4241,9 +4241,12 @@ public abstract class RecentsView { + dividerAnimator.start(); + dividerAnimator.end(); + }); } if (ENABLE_QUICKSTEP_LIVE_TILE.get() && tv.isRunningTask()) { finishRecentsAnimation(false /* toRecents */, null);