Hide bubble dot after flyout init

After the flyout initializes to its collapsed state, hide the
notification dot so that the flyout and dot will seem visually as
one.

Flag: com.android.wm.shell.enable_bubble_bar
Fixes: 376276297
Test: atest BubbleBarFlyoutControllerTest
Change-Id: Ie581ddcd56a26844526f80b2169639c1a7d87500
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index 31b1ea0..fef5c7f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -872,9 +872,14 @@
     /** Animates the bubble bar to notify the user about a bubble change. */
     public void animateBubbleNotification(BubbleBarBubble bubble, boolean isExpanding,
             boolean isUpdate) {
-        // if we're expanded, don't animate the bubble bar. just show the notification dot.
+        // if we're not already animating another bubble, update the dot visibility. otherwise the
+        // the dot will be handled as part of the animation.
+        if (!mBubbleBarViewAnimator.isAnimating()) {
+            bubble.getView().updateDotVisibility(
+                    /* animate= */ !mBubbleStashController.isStashed());
+        }
+        // if we're expanded, don't animate the bubble bar.
         if (isExpanded()) {
-            bubble.getView().updateDotVisibility(/* animate= */ true);
             return;
         }
         boolean isInApp = mTaskbarStashController.isInApp();
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
index 4f3e1ae..114edf4 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
@@ -299,7 +299,8 @@
         return mBubble;
     }
 
-    void updateDotVisibility(boolean animate) {
+    /** Updates the dot visibility if it's not suppressed based on whether it has unseen content. */
+    public void updateDotVisibility(boolean animate) {
         if (mDotSuppressedForBubbleUpdate) {
             // if the dot is suppressed for an update, there's nothing to do
             return;
@@ -321,16 +322,12 @@
         }
     }
 
-    /**
-     * Suppresses or un-suppresses drawing the dot due to an update for this bubble.
-     *
-     * <p>If the dot is being suppressed and is already visible, it remains visible because it is
-     * used as a starting point for the animation. If the dot is being unsuppressed, it is
-     * redrawn if needed.
-     */
+    /** Suppresses or un-suppresses drawing the dot due to an update for this bubble. */
     public void suppressDotForBubbleUpdate(boolean suppress) {
         mDotSuppressedForBubbleUpdate = suppress;
-        if (!suppress) {
+        if (suppress) {
+            setDotScale(0);
+        } else {
             showDotIfNeeded(/* animate= */ false);
         }
     }
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
index eca2bc8..6c354f3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt
@@ -59,7 +59,7 @@
 
     private companion object {
         /** The time to show the flyout. */
-        const val FLYOUT_DELAY_MS: Long = 10000
+        const val FLYOUT_DELAY_MS: Long = 3000
         /** The initial scale Y value that the new bubble is set to before the animation starts. */
         const val BUBBLE_ANIMATION_INITIAL_SCALE_Y = 0.3f
         /** The minimum alpha value to make the bubble bar touchable. */
@@ -484,13 +484,14 @@
         val bubble = bubbleView?.bubble as? BubbleBarBubble
         val flyout = bubble?.flyoutMessage
         if (flyout != null) {
-            bubbleView.suppressDotForBubbleUpdate(true)
             bubbleBarFlyoutController.setUpAndShowFlyout(
-                BubbleBarFlyoutMessage(flyout.icon, flyout.title, flyout.message)
-            ) {
-                moveToState(AnimatingBubble.State.IN)
-                bubbleStashController.updateTaskbarTouchRegion()
-            }
+                BubbleBarFlyoutMessage(flyout.icon, flyout.title, flyout.message),
+                onInit = { bubbleView.suppressDotForBubbleUpdate(true) },
+                onEnd = {
+                    moveToState(AnimatingBubble.State.IN)
+                    bubbleStashController.updateTaskbarTouchRegion()
+                },
+            )
         } else {
             moveToState(AnimatingBubble.State.IN)
         }
@@ -563,7 +564,8 @@
         if (!bubbleBarFlyoutController.hasFlyout()) {
             // if the flyout does not yet exist, then we're only animating the bubble bar.
             // the animating bubble has been updated, so the when the flyout expands it will
-            // show the right message.
+            // show the right message. we only need to update the dot visibility.
+            bubbleView.updateDotVisibility(/* animate= */ !bubbleStashController.isStashed)
             return
         }
 
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutController.kt
index 1452cf6..39e9fac 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutController.kt
@@ -59,7 +59,7 @@
             return rect
         }
 
-    fun setUpAndShowFlyout(message: BubbleBarFlyoutMessage, onEnd: () -> Unit) {
+    fun setUpAndShowFlyout(message: BubbleBarFlyoutMessage, onInit: () -> Unit, onEnd: () -> Unit) {
         flyout?.let(container::removeView)
         val flyout = BubbleBarFlyoutView(container.context, positioner, flyoutScheduler)
 
@@ -76,7 +76,11 @@
         container.addView(flyout, lp)
 
         this.flyout = flyout
-        flyout.showFromCollapsed(message) { showFlyout(AnimationType.MORPH, onEnd) }
+        flyout.showFromCollapsed(message) {
+            flyout.updateExpansionProgress(0f)
+            onInit()
+            showFlyout(AnimationType.MORPH, onEnd)
+        }
     }
 
     private fun showFlyout(animationType: AnimationType, endAction: () -> Unit) {
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutControllerTest.kt
index fef82c1..2997ac9 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/flyout/BubbleBarFlyoutControllerTest.kt
@@ -76,7 +76,7 @@
     @Test
     fun flyoutPosition_left() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync {
-            flyoutController.setUpAndShowFlyout(flyoutMessage) {}
+            setupAndShowFlyout()
             assertThat(flyoutContainer.childCount).isEqualTo(1)
             val flyout = flyoutContainer.getChildAt(0)
             val lp = flyout.layoutParams as FrameLayout.LayoutParams
@@ -89,7 +89,7 @@
     fun flyoutPosition_right() {
         onLeft = false
         InstrumentationRegistry.getInstrumentation().runOnMainSync {
-            flyoutController.setUpAndShowFlyout(flyoutMessage) {}
+            setupAndShowFlyout()
             assertThat(flyoutContainer.childCount).isEqualTo(1)
             val flyout = flyoutContainer.getChildAt(0)
             val lp = flyout.layoutParams as FrameLayout.LayoutParams
@@ -101,7 +101,7 @@
     @Test
     fun flyoutMessage() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync {
-            flyoutController.setUpAndShowFlyout(flyoutMessage) {}
+            setupAndShowFlyout()
             assertThat(flyoutContainer.childCount).isEqualTo(1)
             val flyout = flyoutContainer.getChildAt(0)
             val sender = flyout.findViewById<TextView>(R.id.bubble_flyout_title)
@@ -114,7 +114,7 @@
     @Test
     fun hideFlyout_removedFromContainer() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync {
-            flyoutController.setUpAndShowFlyout(flyoutMessage) {}
+            setupAndShowFlyout()
             assertThat(flyoutController.hasFlyout()).isTrue()
             assertThat(flyoutContainer.childCount).isEqualTo(1)
             flyoutController.collapseFlyout {}
@@ -130,7 +130,7 @@
         // boundary
         flyoutTy = -50f
         InstrumentationRegistry.getInstrumentation().runOnMainSync {
-            flyoutController.setUpAndShowFlyout(flyoutMessage) {}
+            setupAndShowFlyout()
             assertThat(flyoutContainer.childCount).isEqualTo(1)
         }
         InstrumentationRegistry.getInstrumentation().waitForIdleSync()
@@ -143,7 +143,7 @@
     @Test
     fun showFlyout_withinBoundary() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync {
-            flyoutController.setUpAndShowFlyout(flyoutMessage) {}
+            setupAndShowFlyout()
             assertThat(flyoutContainer.childCount).isEqualTo(1)
         }
         InstrumentationRegistry.getInstrumentation().waitForIdleSync()
@@ -156,7 +156,7 @@
     @Test
     fun collapseFlyout_resetsTopBoundary() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync {
-            flyoutController.setUpAndShowFlyout(flyoutMessage) {}
+            setupAndShowFlyout()
             assertThat(flyoutContainer.childCount).isEqualTo(1)
             flyoutController.collapseFlyout {}
             animatorTestRule.advanceTimeBy(300)
@@ -167,7 +167,7 @@
     @Test
     fun cancelFlyout_fadesOutFlyout() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync {
-            flyoutController.setUpAndShowFlyout(flyoutMessage) {}
+            setupAndShowFlyout()
             assertThat(flyoutContainer.childCount).isEqualTo(1)
             val flyoutView = flyoutContainer.findViewById<View>(R.id.bubble_bar_flyout_view)
             assertThat(flyoutView.alpha).isEqualTo(1f)
@@ -181,7 +181,7 @@
     @Test
     fun clickFlyout_notifiesCallback() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync {
-            flyoutController.setUpAndShowFlyout(flyoutMessage) {}
+            setupAndShowFlyout()
             assertThat(flyoutContainer.childCount).isEqualTo(1)
             val flyoutView = flyoutContainer.findViewById<View>(R.id.bubble_bar_flyout_view)
             assertThat(flyoutView.alpha).isEqualTo(1f)
@@ -194,7 +194,7 @@
     @Test
     fun updateFlyoutWhileExpanding() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync {
-            flyoutController.setUpAndShowFlyout(flyoutMessage) {}
+            setupAndShowFlyout()
             assertThat(flyoutController.hasFlyout()).isTrue()
             val flyout = flyoutContainer.findViewById<View>(R.id.bubble_bar_flyout_view)
             assertThat(flyout.findViewById<TextView>(R.id.bubble_flyout_text).text)
@@ -220,7 +220,7 @@
     @Test
     fun updateFlyoutFullyExpanded() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync {
-            flyoutController.setUpAndShowFlyout(flyoutMessage) {}
+            setupAndShowFlyout()
             animatorTestRule.advanceTimeBy(300)
         }
         assertThat(flyoutController.hasFlyout()).isTrue()
@@ -249,7 +249,7 @@
     @Test
     fun updateFlyoutWhileCollapsing() {
         InstrumentationRegistry.getInstrumentation().runOnMainSync {
-            flyoutController.setUpAndShowFlyout(flyoutMessage) {}
+            setupAndShowFlyout()
             animatorTestRule.advanceTimeBy(300)
         }
         assertThat(flyoutController.hasFlyout()).isTrue()
@@ -280,6 +280,10 @@
         assertThat(flyoutController.hasFlyout()).isTrue()
     }
 
+    private fun setupAndShowFlyout() {
+        flyoutController.setUpAndShowFlyout(flyoutMessage, {}, {})
+    }
+
     class FakeFlyoutCallbacks : FlyoutCallbacks {
 
         var topBoundaryExtendedSpace = 0