Hide taskbar content while dreaming. am: f0f94f2ed9

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

Change-Id: I9a701bd2edcc4d0cadff91eb9983c29d0772364c
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
index 941b4b0..c4255bf 100644
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
@@ -49,7 +49,8 @@
     public static final int ALPHA_INDEX_STASHED = 0;
     public static final int ALPHA_INDEX_HOME_DISABLED = 1;
     public static final int ALPHA_INDEX_ASSISTANT_INVOKED = 2;
-    private static final int NUM_ALPHA_CHANNELS = 3;
+    public static final int ALPHA_INDEX_HIDDEN_WHILE_DREAMING = 3;
+    private static final int NUM_ALPHA_CHANNELS = 4;
 
     /**
      * The SharedPreferences key for whether the stashed handle region is dark.
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
index 2628a7f..2fba37e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
@@ -53,6 +53,10 @@
     // Translation property for taskbar background.
     private final AnimatedFloat mBgOffset = new AnimatedFloat(this::updateBackgroundOffset);
 
+    // Used to fade in/out the entirety of the taskbar, for a smooth transition before/after sysui
+    // changes the inset visibility.
+    private final AnimatedFloat mTaskbarAlpha = new AnimatedFloat(this::updateTaskbarAlpha);
+
     // Initialized in init.
     private TaskbarControllers mControllers;
     private TaskbarStashViaTouchController mTaskbarStashViaTouchController;
@@ -83,6 +87,9 @@
         mAssistantBgTaskbar.value = 1;
         mBgOverride.value = 1;
         updateBackgroundAlpha();
+
+        mTaskbarAlpha.value = 1;
+        updateTaskbarAlpha();
     }
 
     public void onDestroy() {
@@ -127,6 +134,10 @@
         return mBgOffset;
     }
 
+    public AnimatedFloat getTaskbarAlpha() {
+        return mTaskbarAlpha;
+    }
+
     /**
      * Make updates when configuration changes.
      */
@@ -165,6 +176,10 @@
         updateOnBackgroundNavButtonColorIntensity();
     }
 
+    private void updateTaskbarAlpha() {
+        mTaskbarDragLayer.setAlpha(mTaskbarAlpha.value);
+    }
+
     @Override
     public void setCornerRoundness(float cornerRoundness) {
         mTaskbarDragLayer.setCornerRoundness(cornerRoundness);
@@ -188,6 +203,7 @@
         pw.println(prefix + "TaskbarDragLayerController:");
 
         pw.println(prefix + "\tmBgOffset=" + mBgOffset.value);
+        pw.println(prefix + "\tmTaskbarAlpha=" + mTaskbarAlpha.value);
         pw.println(prefix + "\tmFolderMargin=" + mFolderMargin);
         pw.println(prefix + "\tmLastSetBackgroundAlpha=" + mLastSetBackgroundAlpha);
         pw.println(prefix + "\t\tmBgOverride=" + mBgOverride.value);
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
index b98ea81..9bc8cdd 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java
@@ -23,11 +23,15 @@
 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_AWAKE;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_DEVICE_DREAMING;
+import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_WAKEFULNESS_MASK;
+import static com.android.systemui.shared.system.QuickStepContract.WAKEFULNESS_AWAKE;
 
 import android.animation.Animator;
 import android.animation.AnimatorListenerAdapter;
 import android.animation.AnimatorSet;
 import android.animation.ObjectAnimator;
+import android.os.SystemClock;
 import android.util.Log;
 
 import androidx.annotation.NonNull;
@@ -93,9 +97,25 @@
      */
     private static final int FLAG_LAUNCHER_WAS_ACTIVE_WHILE_AWAKE = 1 << 4;
 
-    /** Whether the device is currently locked. */
+    /**
+     * Whether the device is currently locked.
+     * <ul>
+     *  <li>While locked, the taskbar is always stashed.<li/>
+     *  <li>Navbar animations on FLAG_DEVICE_LOCKED transitions will get special treatment.</li>
+     * </ul>
+     */
     private static final int FLAG_DEVICE_LOCKED = 1 << 5;
 
+    /**
+     * Whether the complete taskbar is completely hidden (neither visible stashed or unstashed).
+     * This is tracked to allow a nice transition of the taskbar before SysUI forces it away by
+     * hiding the inset.
+     *
+     * This flag is predominanlty set while FLAG_DEVICE_LOCKED is set, thus the taskbar's invisible
+     * resting state while hidden is stashed.
+     */
+    private static final int FLAG_TASKBAR_HIDDEN = 1 << 6;
+
     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;
@@ -104,11 +124,21 @@
     private static final float TASKBAR_BG_ALPHA_NOT_LAUNCHER_NOT_ALIGNED_DELAY_MULT = 0.33f;
     private static final float TASKBAR_BG_ALPHA_LAUNCHER_IS_ALIGNED_DURATION_MULT = 0.25f;
 
+    /**
+     * Delay for the taskbar fade-in.
+     *
+     * Helps to avoid visual noise when unlocking successfully via SFPS, and the device transitions
+     * to launcher directly. The delay avoids the navbar to become briefly visible. The duration
+     * is the same as in SysUI, see http://shortn/_uNSbDoRUSr.
+     */
+    private static final long TASKBAR_SHOW_DELAY_MS = 250;
+
     private final AnimatedFloat mIconAlignment =
             new AnimatedFloat(this::onIconAlignmentRatioChanged);
 
     private TaskbarControllers mControllers;
     private AnimatedFloat mTaskbarBackgroundAlpha;
+    private AnimatedFloat mTaskbarAlpha;
     private AnimatedFloat mTaskbarCornerRoundness;
     private MultiProperty mIconAlphaForHome;
     private QuickstepLauncher mLauncher;
@@ -117,6 +147,9 @@
     private int mState;
     private LauncherState mLauncherState = LauncherState.NORMAL;
 
+    // Time when FLAG_TASKBAR_HIDDEN was last cleared, SystemClock.elapsedRealtime (milliseconds).
+    private long mLastUnlockTimeMs = 0;
+
     private @Nullable TaskBarRecentsAnimationListener mTaskBarRecentsAnimationListener;
 
     private boolean mIsAnimatingToLauncher;
@@ -187,6 +220,7 @@
 
         mTaskbarBackgroundAlpha = mControllers.taskbarDragLayerController
                 .getTaskbarBackgroundAlpha();
+        mTaskbarAlpha = mControllers.taskbarDragLayerController.getTaskbarAlpha();
         mTaskbarCornerRoundness = mControllers.getTaskbarCornerRoundness();
         mIconAlphaForHome = mControllers.taskbarViewController
                 .getTaskbarIconAlpha().get(ALPHA_INDEX_HOME);
@@ -279,6 +313,15 @@
         boolean isDeviceLocked = hasAnyFlag(systemUiStateFlags, MASK_ANY_SYSUI_LOCKED);
         updateStateForFlag(FLAG_DEVICE_LOCKED, isDeviceLocked);
 
+        // Taskbar is hidden whenever the device is dreaming. The dreaming state includes the
+        // interactive dreams, AoD, screen off. Since the SYSUI_STATE_DEVICE_DREAMING only kicks in
+        // when the device is asleep, the second condition extends ensures that the transition from
+        // and to the WAKEFULNESS_ASLEEP state also hide the taskbar, and improves the taskbar
+        // hide/reveal animation timings.
+        boolean isTaskbarHidden = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_DEVICE_DREAMING)
+                || (systemUiStateFlags & SYSUI_STATE_WAKEFULNESS_MASK) != WAKEFULNESS_AWAKE;
+        updateStateForFlag(FLAG_TASKBAR_HIDDEN, isTaskbarHidden);
+
         if (skipAnim) {
             applyState(0);
         } else {
@@ -406,6 +449,41 @@
             AbstractFloatingView.closeAllOpenViews(mControllers.taskbarActivityContext);
         }
 
+        if (hasAnyFlag(changedFlags, FLAG_TASKBAR_HIDDEN) && !hasAnyFlag(FLAG_TASKBAR_HIDDEN)) {
+            // Take note of the current time, as the taskbar is made visible again.
+            mLastUnlockTimeMs = SystemClock.elapsedRealtime();
+        }
+
+        boolean isHidden = hasAnyFlag(FLAG_TASKBAR_HIDDEN);
+        float taskbarAlpha = isHidden ? 0 : 1;
+        if (mTaskbarAlpha.isAnimating() || mTaskbarAlpha.value != taskbarAlpha) {
+            Animator taskbarVisibility = mTaskbarAlpha.animateToValue(taskbarAlpha);
+
+            taskbarVisibility.setDuration(duration);
+            if (isHidden) {
+                // Stash the transient taskbar once the taskbar is not visible. This reduces
+                // visual noise when unlocking the device afterwards.
+                animatorSet.addListener(new AnimatorListenerAdapter() {
+                    @Override
+                    public void onAnimationEnd(Animator animation) {
+                        TaskbarStashController stashController =
+                                mControllers.taskbarStashController;
+                        stashController.updateAndAnimateTransientTaskbar(
+                                /* stash */ true, /* duration */ 0);
+                    }
+                });
+            } else {
+                // delay the fade in animation a bit to reduce visual noise when waking up a device
+                // with a fingerprint reader. This should only be done when the device was woken
+                // up via fingerprint reader, however since this information is currently not
+                // available, opting to always delay the fade-in a bit.
+                long durationSinceLastUnlockMs = SystemClock.elapsedRealtime() - mLastUnlockTimeMs;
+                taskbarVisibility.setStartDelay(
+                        Math.max(0, TASKBAR_SHOW_DELAY_MS - durationSinceLastUnlockMs));
+            }
+            animatorSet.play(taskbarVisibility);
+        }
+
         float backgroundAlpha = isInLauncher && isTaskbarAlignedWithHotseat() ? 0 : 1;
 
         // Don't animate if background has reached desired value.
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
index 92cac7d..5f11740 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java
@@ -505,9 +505,16 @@
     }
 
     /**
-     * Stash or unstashes the transient taskbar.
+     * Stash or unstashes the transient taskbar, using the default TASKBAR_STASH_DURATION.
      */
     public void updateAndAnimateTransientTaskbar(boolean stash) {
+        updateAndAnimateTransientTaskbar(stash, TASKBAR_STASH_DURATION);
+    }
+
+    /**
+     * Stash or unstashes the transient taskbar.
+     */
+    public void updateAndAnimateTransientTaskbar(boolean stash, long duration) {
         if (!DisplayController.isTransientTaskbar(mActivity)) {
             return;
         }
@@ -945,16 +952,8 @@
                 hasAnyFlag(systemUiStateFlags, SYSUI_STATE_SCREEN_PINNING));
 
         boolean isLocked = hasAnyFlag(systemUiStateFlags, MASK_ANY_SYSUI_LOCKED);
-        boolean wasLocked = hasAnyFlag(FLAG_STASHED_DEVICE_LOCKED);
         updateStateForFlag(FLAG_STASHED_DEVICE_LOCKED, isLocked);
 
-        if (isLocked && !wasLocked && DisplayController.isTransientTaskbar(mActivity)) {
-            // Stash the transient taskbar when locking the device. This improves the transition
-            // to AoD (otherwise the taskbar stays a bit too long above the collapsing AoD scrim),
-            // and ensures the taskar state is reset when unlocking the device afterwards.
-            updateStateForFlag(FLAG_STASHED_IN_APP_AUTO, true);
-        }
-
         // Only update FLAG_STASHED_IN_APP_IME when system gesture is not in progress.
         mIsImeShowing = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_IME_SHOWING);
         mIsImeSwitcherShowing = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_IME_SWITCHER_SHOWING);