diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java index 1ceb6533ef..8e1059b1da 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarModelCallbacks.java @@ -54,6 +54,10 @@ public class TaskbarModelCallbacks implements // Initialized in init. private TaskbarControllers mControllers; + // Used to defer any UI updates during the SUW unstash animation. + private boolean mDeferUpdatesForSUW; + private Runnable mDeferredUpdates; + public TaskbarModelCallbacks( TaskbarActivityContext context, TaskbarView container) { mContext = context; @@ -194,10 +198,38 @@ public class TaskbarModelCallbacks implements } hotseatItemInfos = mControllers.taskbarRecentAppsController .updateHotseatItemInfos(hotseatItemInfos); + + if (mDeferUpdatesForSUW) { + ItemInfo[] finalHotseatItemInfos = hotseatItemInfos; + mDeferredUpdates = () -> { + updateHotseatItemsAndBackground(finalHotseatItemInfos); + }; + } else { + updateHotseatItemsAndBackground(hotseatItemInfos); + } + } + + private void updateHotseatItemsAndBackground(ItemInfo[] hotseatItemInfos) { mContainer.updateHotseatItems(hotseatItemInfos); mControllers.taskbarViewController.updateIconsBackground(); } + /** + * This is used to defer UI updates after SUW builds the unstash animation. + * @param defer if true, defers updates to the UI + * if false, posts updates (if any) to the UI + */ + public void setDeferUpdatesForSUW(boolean defer) { + mDeferUpdatesForSUW = defer; + + if (!mDeferUpdatesForSUW) { + if (mDeferredUpdates != null) { + mContainer.post(mDeferredUpdates); + mDeferredUpdates = null; + } + } + } + @Override public void onRunningTasksChanged() { updateRunningApps(); @@ -232,5 +264,7 @@ public class TaskbarModelCallbacks implements pw.println( String.format("%s\tpredicted items count=%s", prefix, mPredictedItems.size())); } + pw.println(String.format("%s\tmDeferUpdatesForSUW=%b", prefix, mDeferUpdatesForSUW)); + pw.println(String.format("%s\tupdates pending=%b", prefix, (mDeferredUpdates != null))); } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 1727dd39f5..17c65e31c0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -586,10 +586,14 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba * actually be used since this animation tracks a swipe progress. */ protected void addUnstashToHotseatAnimation(AnimatorSet animation, int placeholderDuration) { + // Defer any UI updates now to avoid the UI becoming stale when the animation plays. + mControllers.taskbarViewController.setDeferUpdatesForSUW(true); createAnimToIsStashed( /* isStashed= */ false, placeholderDuration, TRANSITION_UNSTASH_SUW_MANUAL); + animation.addListener(AnimatorListeners.forEndCallback( + () -> mControllers.taskbarViewController.setDeferUpdatesForSUW(false))); animation.play(mAnimator); } @@ -805,7 +809,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba } mControllers.taskbarViewController.addRevealAnimToIsStashed(skippable, isStashed, duration, - EMPHASIZED); + EMPHASIZED, animationType == TRANSITION_UNSTASH_SUW_MANUAL); play(skippable, mControllers.stashedHandleViewController .createRevealAnimToIsStashed(isStashed), 0, duration, EMPHASIZED); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 74291857e1..4abd9957b2 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -30,6 +30,7 @@ import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VAL import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_TASKBAR_ALIGNMENT_ANIM; import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_TASKBAR_REVEAL_ANIM; +import android.animation.Animator; import android.animation.AnimatorSet; import android.animation.ObjectAnimator; import android.animation.ValueAnimator; @@ -286,7 +287,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar } private ValueAnimator createRevealAnimForView(View view, boolean isStashed, float newWidth, - boolean isQsb) { + boolean isQsb, boolean dispatchOnAnimationStart) { Rect viewBounds = new Rect(0, 0, view.getWidth(), view.getHeight()); int centerY = viewBounds.centerY(); int halfHandleHeight = mStashedHandleHeight / 2; @@ -318,8 +319,24 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar : 0f; float stashedRadius = stashedRect.height() / 2f; - return new RoundedRectRevealOutlineProvider(radius, stashedRadius, viewBounds, stashedRect) + ValueAnimator reveal = new RoundedRectRevealOutlineProvider(radius, + stashedRadius, viewBounds, stashedRect) .createRevealAnimator(view, !isStashed, 0); + // SUW animation does not dispatch animation start until *after* the animation is complete. + // In order to work properly, the reveal animation start needs to be called immediately. + if (dispatchOnAnimationStart) { + for (Animator.AnimatorListener listener : reveal.getListeners()) { + listener.onAnimationStart(reveal); + } + } + return reveal; + } + + /** + * Defers any updates to the UI for the setup wizard animation. + */ + public void setDeferUpdatesForSUW(boolean defer) { + mModelCallbacks.setDeferUpdatesForSUW(defer); } /** @@ -332,7 +349,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar * @param interpolator The interpolator to use for all animations. */ public void addRevealAnimToIsStashed(AnimatorSet as, boolean isStashed, long duration, - Interpolator interpolator) { + Interpolator interpolator, boolean dispatchOnAnimationStart) { AnimatorSet reveal = new AnimatorSet(); Rect stashedBounds = new Rect(); @@ -349,8 +366,8 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar boolean isQsb = child == mTaskbarView.getQsb(); // Crop the icons to/from the nav handle shape. - reveal.play(createRevealAnimForView(child, isStashed, newChildWidth, isQsb) - .setDuration(duration)); + reveal.play(createRevealAnimForView(child, isStashed, newChildWidth, isQsb, + dispatchOnAnimationStart).setDuration(duration)); // Translate the icons to/from their locations as the "nav handle."