Merge "Do not perform invisible transitions while the screen is off." into tm-qpr-dev am: 42a8fe91db

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/Launcher3/+/21699905

Change-Id: Idc2d27107db630a617102b83f819b5381242f8c1
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 95fea3e..e03c24d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -84,7 +84,6 @@
             };
 
     // Initialized in init.
-    private TaskbarKeyguardController mKeyguardController;
     private final TaskbarLauncherStateController
             mTaskbarLauncherStateController = new TaskbarLauncherStateController();
 
@@ -99,11 +98,12 @@
         mTaskbarLauncherStateController.init(mControllers, mLauncher);
 
         mLauncher.setTaskbarUIController(this);
-        mKeyguardController = taskbarControllers.taskbarKeyguardController;
 
         onLauncherResumedOrPaused(mLauncher.hasBeenResumed(), true /* fromInit */);
 
         onStashedInAppChanged(mLauncher.getDeviceProfile());
+        mTaskbarLauncherStateController.onChangeScreenState(
+                mControllers.getSharedState().sysuiStateFlags, true /* fromInit */);
         mLauncher.addOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener);
     }
 
@@ -121,7 +121,7 @@
     @Override
     protected boolean isTaskbarTouchable() {
         return !(mTaskbarLauncherStateController.isAnimatingToLauncher()
-                && mTaskbarLauncherStateController.goingToAlignedLauncherState());
+                && mTaskbarLauncherStateController.isTaskbarAlignedWithHotseat());
     }
 
     public void setShouldDelayLauncherStateAnim(boolean shouldDelayLauncherStateAnim) {
@@ -169,15 +169,6 @@
     @Nullable
     private Animator onLauncherResumedOrPaused(
             boolean isResumed, boolean fromInit, boolean startAnimation, int duration) {
-        if (mKeyguardController.isScreenOff()) {
-            if (!isResumed) {
-                return null;
-            } else {
-                // Resuming implicitly means device unlocked
-                mKeyguardController.setScreenOn();
-            }
-        }
-
         if (ENABLE_SHELL_TRANSITIONS && isResumed
                 && !mLauncher.getStateManager().getState().isTaskbarAlignedWithHotseat(mLauncher)) {
             // Launcher is resumed, but in a state where taskbar is still independent, so
@@ -329,6 +320,11 @@
     }
 
     @Override
+    public void onChangeScreenState(int screenState) {
+        mTaskbarLauncherStateController.onChangeScreenState(screenState, false /* fromInit */);
+    }
+
+    @Override
     public boolean isIconAlignedWithHotseat() {
         return mTaskbarLauncherStateController.isIconAlignedWithHotseat();
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 6bf83bb..a0adba6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -32,6 +32,7 @@
 import static com.android.launcher3.testing.shared.ResourceUtils.getBoolByName;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_STATE_MASK;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING;
 
 import android.animation.AnimatorSet;
@@ -589,6 +590,9 @@
         mControllers.taskbarForceVisibleImmersiveController.updateSysuiFlags(systemUiStateFlags);
         mControllers.voiceInteractionWindowController.setIsVoiceInteractionWindowVisible(
                 (systemUiStateFlags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0, fromInit);
+
+        mControllers.uiController.onChangeScreenState(
+                systemUiStateFlags & SYSUI_STATE_SCREEN_STATE_MASK);
     }
 
     /**
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
index fb919ee..a6da56d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java
@@ -213,7 +213,6 @@
         uiController.onDestroy();
         rotationButtonController.onDestroy();
         taskbarDragLayerController.onDestroy();
-        taskbarKeyguardController.onDestroy();
         taskbarUnfoldAnimationController.onDestroy();
         taskbarViewController.onDestroy();
         stashedHandleViewController.onDestroy();
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
index 93ba4eb..4e390f1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarKeyguardController.java
@@ -1,19 +1,20 @@
 package com.android.launcher3.taskbar;
 
 import static com.android.launcher3.AbstractFloatingView.TYPE_ALL;
+import static com.android.systemui.shared.system.QuickStepContract.SCREEN_STATE_OFF;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BACK_DISABLED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DOZING;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_HOME_DISABLED;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_ON;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_STATE_MASK;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING;
 import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
 
 import android.app.KeyguardManager;
 
 import com.android.launcher3.AbstractFloatingView;
-import com.android.launcher3.util.ScreenOnTracker;
-import com.android.launcher3.util.ScreenOnTracker.ScreenOnListener;
 import com.android.systemui.shared.system.QuickStepContract;
 
 import java.io.PrintWriter;
@@ -23,36 +24,35 @@
  */
 public class TaskbarKeyguardController implements TaskbarControllers.LoggableTaskbarController {
 
-    private static final int KEYGUARD_SYSUI_FLAGS = SYSUI_STATE_BOUNCER_SHOWING |
-            SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING | SYSUI_STATE_DEVICE_DOZING |
-            SYSUI_STATE_OVERVIEW_DISABLED | SYSUI_STATE_HOME_DISABLED |
-            SYSUI_STATE_BACK_DISABLED | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED;
+    private static final int KEYGUARD_SYSUI_FLAGS = SYSUI_STATE_BOUNCER_SHOWING
+            | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING | SYSUI_STATE_DEVICE_DOZING
+            | SYSUI_STATE_OVERVIEW_DISABLED | SYSUI_STATE_HOME_DISABLED
+            | SYSUI_STATE_BACK_DISABLED | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED
+            | SYSUI_STATE_SCREEN_STATE_MASK;
 
-    private final ScreenOnListener mScreenOnListener;
     private final TaskbarActivityContext mContext;
     private int mKeyguardSysuiFlags;
     private boolean mBouncerShowing;
     private NavbarButtonsViewController mNavbarButtonsViewController;
     private final KeyguardManager mKeyguardManager;
-    private boolean mIsScreenOff;
 
     public TaskbarKeyguardController(TaskbarActivityContext context) {
         mContext = context;
-        mScreenOnListener = isOn -> {
-            if (!isOn) {
-                mIsScreenOff = true;
-                AbstractFloatingView.closeOpenViews(mContext, false, TYPE_ALL);
-            }
-        };
         mKeyguardManager = mContext.getSystemService(KeyguardManager.class);
     }
 
     public void init(NavbarButtonsViewController navbarButtonUIController) {
         mNavbarButtonsViewController = navbarButtonUIController;
-        ScreenOnTracker.INSTANCE.get(mContext).addListener(mScreenOnListener);
     }
 
     public void updateStateForSysuiFlags(int systemUiStateFlags) {
+        int interestingKeyguardFlags = systemUiStateFlags & KEYGUARD_SYSUI_FLAGS;
+        if (interestingKeyguardFlags == mKeyguardSysuiFlags) {
+            // No change in keyguard relevant flags
+            return;
+        }
+        mKeyguardSysuiFlags = interestingKeyguardFlags;
+
         boolean bouncerShowing = (systemUiStateFlags & SYSUI_STATE_BOUNCER_SHOWING) != 0;
         boolean keyguardShowing = (systemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING)
                 != 0;
@@ -60,11 +60,6 @@
                 (systemUiStateFlags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0;
         boolean dozing = (systemUiStateFlags & SYSUI_STATE_DEVICE_DOZING) != 0;
 
-        int interestingKeyguardFlags = systemUiStateFlags & KEYGUARD_SYSUI_FLAGS;
-        if (interestingKeyguardFlags == mKeyguardSysuiFlags) {
-            return;
-        }
-        mKeyguardSysuiFlags = interestingKeyguardFlags;
 
         mBouncerShowing = bouncerShowing;
 
@@ -72,19 +67,17 @@
                 keyguardOccluded);
         updateIconsForBouncer();
 
-        if (keyguardShowing) {
-            AbstractFloatingView.closeOpenViews(mContext, true, TYPE_ALL);
+        boolean screenOffOrTransitioningOff = (systemUiStateFlags & SYSUI_STATE_SCREEN_ON) == 0;
+        boolean closeFloatingViews = keyguardShowing || screenOffOrTransitioningOff;
+
+        if (closeFloatingViews) {
+            // animate the closing of the views, unless the screen is already fully turned off.
+            boolean animateViewClosing =
+                    (systemUiStateFlags & SYSUI_STATE_SCREEN_STATE_MASK) != SCREEN_STATE_OFF;
+            AbstractFloatingView.closeOpenViews(mContext, animateViewClosing, TYPE_ALL);
         }
     }
 
-    public boolean isScreenOff() {
-        return mIsScreenOff;
-    }
-
-    public void setScreenOn() {
-        mIsScreenOff = false;
-    }
-
     /**
      * Hides/shows taskbar when keyguard is up
      */
@@ -95,9 +88,6 @@
         mNavbarButtonsViewController.setBackForBouncer(showBackForBouncer);
     }
 
-    public void onDestroy() {
-        ScreenOnTracker.INSTANCE.get(mContext).removeListener(mScreenOnListener);
-    }
 
     @Override
     public void dumpLogs(String prefix, PrintWriter pw) {
@@ -106,6 +96,5 @@
         pw.println(prefix + "\tmKeyguardSysuiFlags=" + QuickStepContract.getSystemUiStateString(
                 mKeyguardSysuiFlags));
         pw.println(prefix + "\tmBouncerShowing=" + mBouncerShowing);
-        pw.println(prefix + "\tmIsScreenOff=" + mIsScreenOff);
     }
 }
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index 7d5a400..93a0c11 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -18,7 +18,10 @@
 import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP;
 import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_STASHED_LAUNCHER_STATE;
 import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_HOME;
+import static com.android.launcher3.util.FlagDebugUtils.appendFlag;
+import static com.android.launcher3.util.FlagDebugUtils.formatFlagChange;
 import static com.android.systemui.animation.Interpolators.EMPHASIZED;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_ON;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
@@ -53,16 +56,43 @@
  * Track LauncherState, RecentsAnimation, resumed state for task bar in one place here and animate
  * the task bar accordingly.
  */
- public class TaskbarLauncherStateController {
+public class TaskbarLauncherStateController {
 
     private static final String TAG = TaskbarLauncherStateController.class.getSimpleName();
     private static final boolean DEBUG = false;
 
+    /** Launcher activity is resumed and focused. */
     public static final int FLAG_RESUMED = 1 << 0;
-    public static final int FLAG_RECENTS_ANIMATION_RUNNING = 1 << 1;
-    public static final int FLAG_TRANSITION_STATE_RUNNING = 1 << 2;
 
-    private static final int FLAGS_LAUNCHER = FLAG_RESUMED | FLAG_RECENTS_ANIMATION_RUNNING;
+    /**
+     * A external transition / animation is running that will result in FLAG_RESUMED being set.
+     **/
+    public static final int FLAG_TRANSITION_TO_RESUMED = 1 << 1;
+
+    /**
+     * Set while the launcher state machine is performing a state transition, see {@link
+     * StateManager.StateListener}.
+     */
+    public static final int FLAG_LAUNCHER_IN_STATE_TRANSITION = 1 << 2;
+
+    /**
+     * Whether the screen is currently on, or is transitioning to be on.
+     *
+     * This is cleared as soon as the screen begins to transition off.
+     */
+    private static final int FLAG_SCREEN_ON = 1 << 3;
+
+    /**
+     * Captures whether the launcher was active at the time the FLAG_SCREEN_ON was cleared.
+     * Always cleared when FLAG_SCREEN_ON is set.
+     * <p>
+     * FLAG_RESUMED will be cleared when the screen is off, since all apps get paused at this point.
+     * Thus, this flag indicates whether the launcher will be shown when the screen gets turned on
+     * again.
+     */
+    private static final int FLAG_LAUNCHER_ACTIVE_AT_SCREEN_OFF = 1 << 4;
+
+    private static final int FLAGS_LAUNCHER_ACTIVE = FLAG_RESUMED | FLAG_TRANSITION_TO_RESUMED;
     /** Equivalent to an int with all 1s for binary operation purposes */
     private static final int FLAGS_ALL = ~0;
 
@@ -115,12 +145,13 @@
                 @Override
                 public void onStateTransitionStart(LauncherState toState) {
                     if (toState != mLauncherState) {
-                        // Treat FLAG_TRANSITION_STATE_RUNNING as a changed flag even if a previous
-                        // state transition was already running, so we update the new target.
-                        mPrevState &= ~FLAG_TRANSITION_STATE_RUNNING;
+                        // Treat FLAG_LAUNCHER_IN_STATE_TRANSITION as a changed flag even if a
+                        // previous state transition was already running, so we update the new
+                        // target.
+                        mPrevState &= ~FLAG_LAUNCHER_IN_STATE_TRANSITION;
                         mLauncherState = toState;
                     }
-                    updateStateForFlag(FLAG_TRANSITION_STATE_RUNNING, true);
+                    updateStateForFlag(FLAG_LAUNCHER_IN_STATE_TRANSITION, true);
                     if (!mShouldDelayLauncherStateAnim) {
                         if (toState == LauncherState.NORMAL) {
                             applyState(QuickstepTransitionManager.TASKBAR_TO_HOME_DURATION);
@@ -133,7 +164,7 @@
                 @Override
                 public void onStateTransitionComplete(LauncherState finalState) {
                     mLauncherState = finalState;
-                    updateStateForFlag(FLAG_TRANSITION_STATE_RUNNING, false);
+                    updateStateForFlag(FLAG_LAUNCHER_IN_STATE_TRANSITION, false);
                     applyState();
                     boolean disallowLongClick = finalState == LauncherState.OVERVIEW_SPLIT_SELECT;
                     com.android.launcher3.taskbar.Utilities.setOverviewDragState(
@@ -159,9 +190,6 @@
         resetIconAlignment();
 
         mLauncher.getStateManager().addStateListener(mStateListener);
-
-        // Initialize to the current launcher state
-        updateStateForFlag(FLAG_RESUMED, launcher.hasBeenResumed());
         mLauncherState = launcher.getStateManager().getState();
         applyState(0);
 
@@ -182,6 +210,12 @@
         mLauncher.removeOnDeviceProfileChangeListener(mOnDeviceProfileChangeListener);
     }
 
+    /**
+     * Creates a transition animation to the launcher activity.
+     *
+     * Warning: the resulting animation must be played, since this method has side effects on this
+     * controller's state.
+     */
     public Animator createAnimToLauncher(@NonNull LauncherState toState,
             @NonNull RecentsAnimationCallbacks callbacks, long duration) {
         // If going to overview, stash the task bar
@@ -197,7 +231,7 @@
         }
         stashController.updateStateForFlag(FLAG_IN_APP, false);
 
-        updateStateForFlag(FLAG_RECENTS_ANIMATION_RUNNING, true);
+        updateStateForFlag(FLAG_TRANSITION_TO_RESUMED, true);
         animatorSet.play(stashController.createApplyStateAnimator(duration));
         animatorSet.play(applyState(duration, false));
 
@@ -225,12 +259,30 @@
         mShouldDelayLauncherStateAnim = shouldDelayLauncherStateAnim;
     }
 
+    /** Screen state changed, see QuickStepContract.SCREEN_STATE_* values. */
+    public void onChangeScreenState(int screenState, boolean fromInit) {
+        final boolean prevScreenIsOn = hasAnyFlag(FLAG_SCREEN_ON);
+        final boolean currScreenIsOn = hasAnyFlag(screenState, SYSUI_STATE_SCREEN_ON);
+
+        if (prevScreenIsOn == currScreenIsOn) return;
+
+        updateStateForFlag(FLAG_SCREEN_ON, currScreenIsOn);
+        updateStateForFlag(FLAG_LAUNCHER_ACTIVE_AT_SCREEN_OFF,
+                prevScreenIsOn && hasAnyFlag(FLAGS_LAUNCHER_ACTIVE));
+
+        if (fromInit) {
+            applyState(0);
+        } else {
+            applyState();
+        }
+    }
+
     /**
      * Updates the proper flag to change the state of the task bar.
      *
      * Note that this only updates the flag. {@link #applyState()} needs to be called separately.
      *
-     * @param flag The flag to update.
+     * @param flag    The flag to update.
      * @param enabled Whether to enable the flag
      */
     public void updateStateForFlag(int flag, boolean enabled) {
@@ -269,6 +321,19 @@
         if (mPrevState == null || mPrevState != mState) {
             // If this is our initial state, treat all flags as changed.
             int changedFlags = mPrevState == null ? FLAGS_ALL : mPrevState ^ mState;
+
+            if (DEBUG) {
+                String stateString;
+                if (mPrevState == null) {
+                    stateString = getStateString(mState) + "(initial update)";
+                } else {
+                    stateString = formatFlagChange(mState, mPrevState,
+                            TaskbarLauncherStateController::getStateString);
+                }
+                Log.d(TAG, "applyState: " + stateString
+                        + ", duration: " + duration
+                        + ", start: " + start);
+            }
             mPrevState = mState;
             animator = onStateChangeApplied(changedFlags, duration, start);
         }
@@ -276,26 +341,23 @@
     }
 
     private Animator onStateChangeApplied(int changedFlags, long duration, boolean start) {
-        final boolean goingToLauncher = isInLauncher();
+        final boolean isInLauncher = isInLauncher();
         final boolean isIconAlignedWithHotseat = isIconAlignedWithHotseat();
         final float toAlignment = isIconAlignedWithHotseat ? 1 : 0;
         boolean handleOpenFloatingViews = false;
         if (DEBUG) {
-            Log.d(TAG, "onStateChangeApplied - mState: " + getStateString(mState)
-                    + ", changedFlags: " + getStateString(changedFlags)
-                    + ", goingToLauncher: " + goingToLauncher
+            Log.d(TAG, "onStateChangeApplied - isInLauncher: " + isInLauncher
                     + ", mLauncherState: " + mLauncherState
                     + ", toAlignment: " + toAlignment);
         }
         AnimatorSet animatorSet = new AnimatorSet();
 
-        // Add the state animation first to ensure FLAG_IN_STASHED_LAUNCHER_STATE is set and we can
-        // determine whether goingToUnstashedLauncherStateChanged.
-        if (hasAnyFlag(changedFlags, FLAG_TRANSITION_STATE_RUNNING)) {
-            boolean committed = !hasAnyFlag(FLAG_TRANSITION_STATE_RUNNING);
-            playStateTransitionAnim(animatorSet, duration, committed);
+        if (hasAnyFlag(changedFlags, FLAG_LAUNCHER_IN_STATE_TRANSITION)) {
+            boolean launcherTransitionCompleted = !hasAnyFlag(FLAG_LAUNCHER_IN_STATE_TRANSITION);
+            playStateTransitionAnim(animatorSet, duration, launcherTransitionCompleted);
 
-            if (committed && mLauncherState == LauncherState.QUICK_SWITCH_FROM_HOME) {
+            if (launcherTransitionCompleted
+                    && mLauncherState == LauncherState.QUICK_SWITCH_FROM_HOME) {
                 // We're about to be paused, set immediately to ensure seamless handoff.
                 updateStateForFlag(FLAG_RESUMED, false);
                 applyState(0 /* duration */);
@@ -306,37 +368,37 @@
             }
         }
 
-        if (hasAnyFlag(changedFlags, FLAGS_LAUNCHER)) {
+        if (hasAnyFlag(changedFlags, FLAGS_LAUNCHER_ACTIVE)) {
             animatorSet.addListener(new AnimatorListenerAdapter() {
                 @Override
-                public void onAnimationEnd(Animator animation) {
-                    mIsAnimatingToLauncher = false;
-                }
-
-                @Override
                 public void onAnimationStart(Animator animation) {
-                    mIsAnimatingToLauncher = goingToLauncher;
+                    mIsAnimatingToLauncher = isInLauncher;
 
                     TaskbarStashController stashController =
                             mControllers.taskbarStashController;
                     if (DEBUG) {
-                        Log.d(TAG, "onAnimationStart - FLAG_IN_APP: " + !goingToLauncher);
+                        Log.d(TAG, "onAnimationStart - FLAG_IN_APP: " + !isInLauncher);
                     }
-                    stashController.updateStateForFlag(FLAG_IN_APP, !goingToLauncher);
+                    stashController.updateStateForFlag(FLAG_IN_APP, !isInLauncher);
                     stashController.applyState(duration);
                 }
+
+                @Override
+                public void onAnimationEnd(Animator animation) {
+                    mIsAnimatingToLauncher = false;
+                }
             });
 
             // Handle closing open popups when going home/overview
             handleOpenFloatingViews = true;
         }
-        if (handleOpenFloatingViews && goingToLauncher) {
+
+        if (handleOpenFloatingViews && isInLauncher) {
             AbstractFloatingView.closeAllOpenViews(mControllers.taskbarActivityContext);
         }
 
-        float backgroundAlpha =
-                goingToLauncher && mLauncherState.isTaskbarAlignedWithHotseat(mLauncher)
-                        ? 0 : 1;
+        float backgroundAlpha = isInLauncher && isTaskbarAlignedWithHotseat() ? 0 : 1;
+
         // Don't animate if background has reached desired value.
         if (mTaskbarBackgroundAlpha.isAnimating()
                 || mTaskbarBackgroundAlpha.value != backgroundAlpha) {
@@ -347,21 +409,20 @@
                         + " -> " + backgroundAlpha + ": " + duration);
             }
 
-            boolean goingToLauncherIconNotAligned = goingToLauncher && !isIconAlignedWithHotseat;
-            boolean notGoingToLauncherIconNotAligned = !goingToLauncher
-                    && !isIconAlignedWithHotseat;
-            boolean goingToLauncherIconIsAligned = goingToLauncher && isIconAlignedWithHotseat;
+            boolean isInLauncherIconNotAligned = isInLauncher && !isIconAlignedWithHotseat;
+            boolean notInLauncherIconNotAligned = !isInLauncher && !isIconAlignedWithHotseat;
+            boolean isInLauncherIconIsAligned = isInLauncher && isIconAlignedWithHotseat;
 
             float startDelay = 0;
             // We want to delay the background from fading in so that the icons have time to move
             // into the bounds of the background before it appears.
-            if (goingToLauncherIconNotAligned) {
+            if (isInLauncherIconNotAligned) {
                 startDelay = duration * TASKBAR_BG_ALPHA_LAUNCHER_NOT_ALIGNED_DELAY_MULT;
-            } else if (notGoingToLauncherIconNotAligned) {
+            } else if (notInLauncherIconNotAligned) {
                 startDelay = duration * TASKBAR_BG_ALPHA_NOT_LAUNCHER_NOT_ALIGNED_DELAY_MULT;
             }
             float newDuration = duration - startDelay;
-            if (goingToLauncherIconIsAligned) {
+            if (isInLauncherIconIsAligned) {
                 // Make the background fade out faster so that it is gone by the time the
                 // icons move outside of the bounds of the background.
                 newDuration = duration * TASKBAR_BG_ALPHA_LAUNCHER_IS_ALIGNED_DURATION_MULT;
@@ -373,7 +434,8 @@
             animatorSet.play(taskbarBackgroundAlpha);
         }
 
-        float cornerRoundness = goingToLauncher ? 0 : 1;
+        float cornerRoundness = isInLauncher ? 0 : 1;
+
         // Don't animate if corner roundness has reached desired value.
         if (mTaskbarCornerRoundness.isAnimating()
                 || mTaskbarCornerRoundness.value != cornerRoundness) {
@@ -412,8 +474,12 @@
         return animatorSet;
     }
 
-    /** Returns whether we're going to a state where taskbar icons should align with launcher. */
-    public boolean goingToAlignedLauncherState() {
+    /**
+     * Whether the taskbar is aligned with the hotseat in the current/target launcher state.
+     *
+     * This refers to the intended state - a transition to this state might be in progress.
+     */
+    public boolean isTaskbarAlignedWithHotseat() {
         return mLauncherState.isTaskbarAlignedWithHotseat(mLauncher);
     }
 
@@ -481,8 +547,13 @@
         }
     }
 
+    /** Whether the launcher is considered active. */
     private boolean isInLauncher() {
-        return (mState & FLAGS_LAUNCHER) != 0;
+        if (hasAnyFlag(FLAG_SCREEN_ON)) {
+            return hasAnyFlag(FLAGS_LAUNCHER_ACTIVE);
+        } else {
+            return hasAnyFlag(FLAG_LAUNCHER_ACTIVE_AT_SCREEN_OFF);
+        }
     }
 
     /**
@@ -509,7 +580,8 @@
         if (firstFrameVisChanged && mCanSyncViews && !Utilities.isRunningInTestHarness()) {
             ViewRootSync.synchronizeNextDraw(mLauncher.getHotseat(),
                     mControllers.taskbarActivityContext.getDragLayer(),
-                    () -> {});
+                    () -> {
+                    });
         }
     }
 
@@ -562,7 +634,7 @@
 
             // Update the resumed state immediately to ensure a seamless handoff
             boolean launcherResumed = !finishedToApp;
-            updateStateForFlag(FLAG_RECENTS_ANIMATION_RUNNING, false);
+            updateStateForFlag(FLAG_TRANSITION_TO_RESUMED, false);
             updateStateForFlag(FLAG_RESUMED, launcherResumed);
             applyState();
 
@@ -576,17 +648,15 @@
     }
 
     private static String getStateString(int flags) {
-        StringJoiner str = new StringJoiner("|");
-        if ((flags & FLAG_RESUMED) != 0) {
-            str.add("FLAG_RESUMED");
-        }
-        if ((flags & FLAG_RECENTS_ANIMATION_RUNNING) != 0) {
-            str.add("FLAG_RECENTS_ANIMATION_RUNNING");
-        }
-        if ((flags & FLAG_TRANSITION_STATE_RUNNING) != 0) {
-            str.add("FLAG_TRANSITION_STATE_RUNNING");
-        }
-        return str.toString();
+        StringJoiner result = new StringJoiner("|");
+        appendFlag(result, flags, FLAG_RESUMED, "resumed");
+        appendFlag(result, flags, FLAG_TRANSITION_TO_RESUMED, "transition_to_resumed");
+        appendFlag(result, flags, FLAG_LAUNCHER_IN_STATE_TRANSITION,
+                "launcher_in_state_transition");
+        appendFlag(result, flags, FLAG_SCREEN_ON, "screen_on");
+        appendFlag(result, flags, FLAG_LAUNCHER_ACTIVE_AT_SCREEN_OFF,
+                "launcher_active_at_screen_off");
+        return result.toString();
     }
 
     protected void dumpLogs(String prefix, PrintWriter pw) {
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 30cfcdf..b613763 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -81,7 +81,7 @@
 
     public static final int FLAG_IN_APP = 1 << 0;
     public static final int FLAG_STASHED_IN_APP_MANUAL = 1 << 1; // long press, persisted
-    public static final int FLAG_STASHED_IN_SYSUI_STATE = 1 << 2; // app pinning, keyguard, etc.
+    public static final int FLAG_STASHED_IN_APP_SYSUI = 1 << 2; // shade open, ...
     public static final int FLAG_STASHED_IN_APP_SETUP = 1 << 3; // setup wizard and AllSetActivity
     public static final int FLAG_STASHED_IN_APP_IME = 1 << 4; // IME is visible
     public static final int FLAG_IN_STASHED_LAUNCHER_STATE = 1 << 5;
@@ -89,13 +89,14 @@
     public static final int FLAG_IN_SETUP = 1 << 7; // In the Setup Wizard
     public static final int FLAG_STASHED_SMALL_SCREEN = 1 << 8; // phone screen gesture nav, stashed
     public static final int FLAG_STASHED_IN_APP_AUTO = 1 << 9; // Autohide (transient taskbar).
+    public static final int FLAG_STASHED_SYSUI = 1 << 10; //  app pinning, keyguard, etc.
 
     // If any of these flags are enabled, isInApp should return true.
     private static final int FLAGS_IN_APP = FLAG_IN_APP | FLAG_IN_SETUP;
 
     // If we're in an app and any of these flags are enabled, taskbar should be stashed.
     private static final int FLAGS_STASHED_IN_APP = FLAG_STASHED_IN_APP_MANUAL
-            | FLAG_STASHED_IN_SYSUI_STATE | FLAG_STASHED_IN_APP_SETUP
+            | FLAG_STASHED_IN_APP_SYSUI | FLAG_STASHED_IN_APP_SETUP
             | FLAG_STASHED_IN_APP_IME | FLAG_STASHED_IN_TASKBAR_ALL_APPS
             | FLAG_STASHED_SMALL_SCREEN | FLAG_STASHED_IN_APP_AUTO;
 
@@ -218,11 +219,11 @@
                 boolean inApp = hasAnyFlag(flags, FLAGS_IN_APP);
                 boolean stashedInApp = hasAnyFlag(flags, FLAGS_STASHED_IN_APP);
                 boolean stashedLauncherState = hasAnyFlag(flags, FLAG_IN_STASHED_LAUNCHER_STATE);
-                boolean stashedInTaskbarAllApps =
-                        hasAnyFlag(flags, FLAG_STASHED_IN_TASKBAR_ALL_APPS);
-                boolean stashedForSmallScreen = hasAnyFlag(flags, FLAG_STASHED_SMALL_SCREEN);
-                return (inApp && stashedInApp) || (!inApp && stashedLauncherState)
-                        || stashedInTaskbarAllApps || stashedForSmallScreen;
+                boolean forceStashed = hasAnyFlag(flags,
+                        FLAG_STASHED_SYSUI
+                                | FLAG_STASHED_IN_TASKBAR_ALL_APPS
+                                | FLAG_STASHED_SMALL_SCREEN);
+                return (inApp && stashedInApp) || (!inApp && stashedLauncherState) || forceStashed;
             });
 
     public TaskbarStashController(TaskbarActivityContext activity) {
@@ -901,13 +902,14 @@
         long animDuration = TASKBAR_STASH_DURATION;
         long startDelay = 0;
 
-        updateStateForFlag(FLAG_STASHED_IN_SYSUI_STATE, hasAnyFlag(systemUiStateFlags,
+        updateStateForFlag(FLAG_STASHED_IN_APP_SYSUI, hasAnyFlag(systemUiStateFlags,
+                SYSUI_STATE_QUICK_SETTINGS_EXPANDED
+                        | SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED));
+        updateStateForFlag(FLAG_STASHED_SYSUI, hasAnyFlag(systemUiStateFlags,
                 SYSUI_STATE_SCREEN_PINNING
                         | SYSUI_STATE_BOUNCER_SHOWING
                         | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING
-                        | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED
-                        | SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED
-                        | SYSUI_STATE_QUICK_SETTINGS_EXPANDED));
+                        | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED));
 
         // Only update FLAG_STASHED_IN_APP_IME when system gesture is not in progress.
         mIsImeShowing = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_IME_SHOWING);
@@ -1071,13 +1073,14 @@
         StringJoiner sj = new StringJoiner("|");
         appendFlag(sj, flags, FLAGS_IN_APP, "FLAG_IN_APP");
         appendFlag(sj, flags, FLAG_STASHED_IN_APP_MANUAL, "FLAG_STASHED_IN_APP_MANUAL");
-        appendFlag(sj, flags, FLAG_STASHED_IN_SYSUI_STATE, "FLAG_STASHED_IN_SYSUI_STATE");
+        appendFlag(sj, flags, FLAG_STASHED_IN_APP_SYSUI, "FLAG_STASHED_IN_APP_SYSUI");
         appendFlag(sj, flags, FLAG_STASHED_IN_APP_SETUP, "FLAG_STASHED_IN_APP_SETUP");
         appendFlag(sj, flags, FLAG_STASHED_IN_APP_IME, "FLAG_STASHED_IN_APP_IME");
         appendFlag(sj, flags, FLAG_IN_STASHED_LAUNCHER_STATE, "FLAG_IN_STASHED_LAUNCHER_STATE");
         appendFlag(sj, flags, FLAG_STASHED_IN_TASKBAR_ALL_APPS, "FLAG_STASHED_IN_TASKBAR_ALL_APPS");
         appendFlag(sj, flags, FLAG_IN_SETUP, "FLAG_IN_SETUP");
         appendFlag(sj, flags, FLAG_STASHED_IN_APP_AUTO, "FLAG_STASHED_IN_APP_AUTO");
+        appendFlag(sj, flags, FLAG_STASHED_SYSUI, "FLAG_STASHED_SYSUI");
         return sj.toString();
     }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index 4c6d3fa..8046cd6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -125,6 +125,12 @@
     }
 
     /**
+     * Screen state changed, see QuickStepContract.SCREEN_STATE_* values.
+     */
+    public void onChangeScreenState(int screenState){
+    }
+
+    /**
      * Returns {@code true} iff taskbar is stashed.
      */
     public boolean isTaskbarStashed() {