diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index aae8a56593..3fe25b9001 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -40,12 +40,14 @@ import static com.android.app.animation.Interpolators.DECELERATE_1_5; import static com.android.app.animation.Interpolators.DECELERATE_1_7; import static com.android.app.animation.Interpolators.EXAGGERATED_EASE; import static com.android.app.animation.Interpolators.LINEAR; +import static com.android.launcher3.BaseActivity.EVENT_DESTROYED; import static com.android.launcher3.BaseActivity.INVISIBLE_ALL; import static com.android.launcher3.BaseActivity.INVISIBLE_BY_APP_TRANSITIONS; import static com.android.launcher3.BaseActivity.INVISIBLE_BY_PENDING_FLAGS; import static com.android.launcher3.BaseActivity.PENDING_INVISIBLE_BY_WALLPAPER_ANIMATION; import static com.android.launcher3.Flags.enableContainerReturnAnimations; import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation; +import static com.android.launcher3.Flags.syncAppLaunchWithTaskbarStash; import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.LauncherState.BACKGROUND_APP; @@ -356,6 +358,20 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener options.setOnAnimationAbortListener(endCallback); options.setOnAnimationFinishedListener(endCallback); options.setLaunchCookie(StableViewInfo.toLaunchCookie(itemInfo)); + + // Prepare taskbar for animation synchronization. This needs to happen here before any + // app transition is created. + LauncherTaskbarUIController taskbarController = mLauncher.getTaskbarUIController(); + if (syncAppLaunchWithTaskbarStash() + && enableScalingRevealHomeAnimation() + && taskbarController != null) { + taskbarController.setIgnoreInAppFlagForSync(true); + mLauncher.addEventCallback(EVENT_DESTROYED, onEndCallback::executeAllAndDestroy); + onEndCallback.add(() -> { + taskbarController.setIgnoreInAppFlagForSync(false); + }); + } + return new ActivityOptionsWrapper(options, onEndCallback); } @@ -1903,6 +1919,21 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener anim.addListener(mForceInvisibleListener); } + // Syncs the app launch animation and taskbar stash animation (if exists). + if (syncAppLaunchWithTaskbarStash() && enableScalingRevealHomeAnimation()) { + LauncherTaskbarUIController taskbarController = mLauncher.getTaskbarUIController(); + if (taskbarController != null) { + taskbarController.setIgnoreInAppFlagForSync(false); + + if (launcherClosing) { + Animator taskbar = taskbarController.createAnimToApp(); + if (taskbar != null) { + anim.play(taskbar); + } + } + } + } + result.setAnimation(anim, mLauncher, mOnEndCallback::executeAllAndDestroy, skipFirstFrame); } diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index e998388f33..6e210e337d 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -17,12 +17,14 @@ package com.android.launcher3.taskbar; import static android.window.DesktopModeFlags.ENABLE_DESKTOP_WINDOWING_WALLPAPER_ACTIVITY; +import static com.android.launcher3.Flags.syncAppLaunchWithTaskbarStash; import static com.android.launcher3.QuickstepTransitionManager.TASKBAR_TO_APP_DURATION; import static com.android.launcher3.QuickstepTransitionManager.TRANSIENT_TASKBAR_TRANSITION_DURATION; import static com.android.launcher3.QuickstepTransitionManager.getTaskbarToHomeDuration; import static com.android.launcher3.statemanager.BaseState.FLAG_NON_INTERACTIVE; import static com.android.launcher3.taskbar.TaskbarEduTooltipControllerKt.TOOLTIP_STEP_FEATURES; import static com.android.launcher3.taskbar.TaskbarLauncherStateController.FLAG_VISIBLE; +import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IGNORE_IN_APP; import android.animation.Animator; import android.animation.AnimatorSet; @@ -301,6 +303,29 @@ public class LauncherTaskbarUIController extends TaskbarUIController { return mTaskbarLauncherStateController.createAnimToLauncher(toState, callbacks, duration); } + /** + * Create Taskbar animation to be played alongside the Launcher app launch animation. + */ + public @Nullable Animator createAnimToApp() { + if (!syncAppLaunchWithTaskbarStash()) { + return null; + } + TaskbarStashController stashController = mControllers.taskbarStashController; + stashController.updateStateForFlag(TaskbarStashController.FLAG_IN_APP, true); + return stashController.createApplyStateAnimator(stashController.getStashDuration()); + } + + /** + * Temporarily ignore FLAG_IN_APP for app launches to prevent premature taskbar stashing. + * This is needed because taskbar gets a signal to stash before we actually start the + * app launch animation. + */ + public void setIgnoreInAppFlagForSync(boolean enabled) { + if (syncAppLaunchWithTaskbarStash()) { + mControllers.taskbarStashController.updateStateForFlag(FLAG_IGNORE_IN_APP, enabled); + } + } + public void updateTaskbarLauncherStateGoingHome() { mTaskbarLauncherStateController.updateStateForFlag(FLAG_VISIBLE, true); mTaskbarLauncherStateController.applyState(); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 5284edd620..ad59c2e9d7 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -23,6 +23,7 @@ import static com.android.app.animation.Interpolators.INSTANT; import static com.android.app.animation.Interpolators.LINEAR; import static com.android.internal.jank.InteractionJankMonitor.Configuration; import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation; +import static com.android.launcher3.Flags.syncAppLaunchWithTaskbarStash; import static com.android.launcher3.QuickstepTransitionManager.PINNED_TASKBAR_TRANSITION_DURATION; import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NAVBAR_UNIFICATION; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TRANSIENT_TASKBAR_HIDE; @@ -107,6 +108,8 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba // taskbar should always be stashed for bubble bar on phone public static final int FLAG_STASHED_BUBBLE_BAR_ON_PHONE = 1 << 15; + public static final int FLAG_IGNORE_IN_APP = 1 << 16; // used to sync with app launch animation + // If any of these flags are enabled, isInApp should return true. private static final int FLAGS_IN_APP = FLAG_IN_APP | FLAG_IN_SETUP; @@ -1412,6 +1415,13 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba */ @Nullable public Animator createSetStateAnimator(long flags, long duration) { + // We do this when we want to synchronize the app launch and taskbar stash animations. + if (syncAppLaunchWithTaskbarStash() + && hasAnyFlag(FLAG_IGNORE_IN_APP) + && hasAnyFlag(flags, FLAG_IN_APP)) { + flags = flags & ~FLAG_IN_APP; + } + boolean isStashed = mStashCondition.test(flags); if (DEBUG) {