Loading quickstep/res/values/ids.xml +2 −0 Original line number Diff line number Diff line Loading @@ -19,4 +19,6 @@ <item type="id" name="action_move_left" /> <item type="id" name="action_move_right" /> <item type="id" name="action_dismiss_all" /> <item type="id" name="bubble_bar_flyout_view" /> </resources> No newline at end of file quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java +0 −2 Original line number Diff line number Diff line Loading @@ -377,8 +377,6 @@ public class BubbleBarController extends IBubblesListener.Stub { // Updates mean the dot state may have changed; any other changes were updated in // the populateBubble step. BubbleBarBubble bb = mBubbles.get(update.updatedBubble.getKey()); // If we're not stashed, we're visible so animate bb.getView().updateDotVisibility(!mBubbleStashController.isStashed() /* animate */); mBubbleBarViewController.animateBubbleNotification( bb, /* isExpanding= */ false, /* isUpdate= */ true); } Loading quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java +9 −4 Original line number Diff line number Diff line Loading @@ -148,7 +148,8 @@ public class BubbleBarViewController { mBubbleBarFlyoutController = new BubbleBarFlyoutController( mBubbleBarContainer, createFlyoutPositioner(), createFlyoutTopBoundaryListener()); mBubbleBarViewAnimator = new BubbleBarViewAnimator( mBarView, mBubbleStashController, mBubbleBarController::showExpandedView); mBarView, mBubbleStashController, mBubbleBarFlyoutController, mBubbleBarController::showExpandedView); mTaskbarViewPropertiesProvider = taskbarViewPropertiesProvider; onBubbleBarConfigurationChanged(/* animate= */ false); mActivity.addOnDeviceProfileChangeListener( Loading Loading @@ -781,6 +782,11 @@ public class BubbleBarViewController { /** 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 (isExpanded()) { bubble.getView().updateDotVisibility(/* animate= */ true); return; } boolean isInApp = mTaskbarStashController.isInApp(); // if this is the first bubble, animate to the initial state. if (mBarView.getBubbleChildCount() == 1 && !isUpdate) { Loading @@ -789,13 +795,12 @@ public class BubbleBarViewController { } boolean persistentTaskbarOrOnHome = mBubbleStashController.isBubblesShowingOnHome() || !mBubbleStashController.isTransientTaskBar(); if (persistentTaskbarOrOnHome && !isExpanded()) { if (persistentTaskbarOrOnHome) { mBubbleBarViewAnimator.animateBubbleBarForCollapsed(bubble, isExpanding); return; } // only animate the new bubble if we're in an app, have handle view and not auto expanding if (isInApp && mBubbleStashController.getHasHandleView() && !isExpanded()) { if (isInApp && mBubbleStashController.getHasHandleView()) { mBubbleBarViewAnimator.animateBubbleInForStashed(bubble, isExpanding); } } Loading quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java +1 −1 Original line number Diff line number Diff line Loading @@ -301,7 +301,7 @@ public class BubbleView extends ConstraintLayout { void updateDotVisibility(boolean animate) { if (mDotSuppressedForBubbleUpdate) { // if the dot is suppressed for // if the dot is suppressed for an update, there's nothing to do return; } final float targetScale = hasUnseenContent() ? 1f : 0f; Loading quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt +63 −16 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import com.android.launcher3.R import com.android.launcher3.taskbar.bubbles.BubbleBarBubble import com.android.launcher3.taskbar.bubbles.BubbleBarView import com.android.launcher3.taskbar.bubbles.BubbleView import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutController import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutMessage import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController import com.android.wm.shell.shared.animation.PhysicsAnimator Loading @@ -36,8 +38,9 @@ class BubbleBarViewAnimator constructor( private val bubbleBarView: BubbleBarView, private val bubbleStashController: BubbleStashController, private val bubbleBarFlyoutController: BubbleBarFlyoutController, private val onExpanded: Runnable, private val scheduler: Scheduler = HandlerScheduler(bubbleBarView) private val scheduler: Scheduler = HandlerScheduler(bubbleBarView), ) { private var animatingBubble: AnimatingBubble? = null Loading @@ -54,7 +57,7 @@ constructor( private companion object { /** The time to show the flyout. */ const val FLYOUT_DELAY_MS: Long = 2500 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. */ Loading @@ -69,7 +72,7 @@ constructor( val showAnimation: Runnable, val hideAnimation: Runnable, val expand: Boolean, val state: State = State.CREATED val state: State = State.CREATED, ) { /** Loading @@ -91,7 +94,7 @@ constructor( /** The bubble notification is now fully showing and waiting to be hidden. */ IN, /** The bubble notification is animating out. */ ANIMATING_OUT ANIMATING_OUT, } } Loading Loading @@ -127,7 +130,7 @@ constructor( private val springConfig = PhysicsAnimator.SpringConfig( stiffness = SpringForce.STIFFNESS_LOW, dampingRatio = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY dampingRatio = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY, ) /** Animates a bubble for the state where the bubble bar is stashed. */ Loading @@ -137,8 +140,9 @@ constructor( val bubbleView = b.view val animator = PhysicsAnimator.getInstance(bubbleView) if (animator.isRunning()) animator.cancel() // the animation of a new bubble is divided into 2 parts. The first part shows the bubble // and the second part hides it after a delay. // the animation of a new bubble is divided into 2 parts. The first part transforms the // handle to the bubble bar and then shows the flyout. The second part hides the flyout and // transforms the bubble bar back to the handle. val showAnimation = buildHandleToBubbleBarAnimation() val hideAnimation = if (isExpanding) Runnable {} else buildBubbleBarToHandleAnimation() animatingBubble = Loading Loading @@ -243,7 +247,8 @@ constructor( cancelHideAnimation() return@addEndListener } moveToState(AnimatingBubble.State.IN) setupAndShowFlyout() // the bubble bar is now fully settled in. update taskbar touch region so it's touchable bubbleStashController.updateTaskbarTouchRegion() } Loading Loading @@ -316,8 +321,18 @@ constructor( bubbleBarView.scaleY = 1f bubbleStashController.updateTaskbarTouchRegion() } val bubble = animatingBubble?.bubbleView?.bubble as? BubbleBarBubble val flyout = bubble?.flyoutMessage if (flyout != null) { bubbleBarFlyoutController.collapseFlyout { onFlyoutRemoved(bubble.view) animator.start() } } else { animator.start() } } /** Animates to the initial state of the bubble bar, when there are no previous bubbles. */ fun animateToInitialState(b: BubbleBarBubble, isInApp: Boolean, isExpanding: Boolean) { Loading @@ -326,16 +341,16 @@ constructor( val bubbleView = b.view val animator = PhysicsAnimator.getInstance(bubbleView) if (animator.isRunning()) animator.cancel() // the animation of a new bubble is divided into 2 parts. The first part shows the bubble // and the second part hides it after a delay if we are in an app. // the animation of a new bubble is divided into 2 parts. The first part slides in the // bubble bar and shows the flyout. The second part hides the flyout and transforms the // bubble bar to the handle if we're in an app. val showAnimation = buildBubbleBarSpringInAnimation() val hideAnimation = if (isInApp && !isExpanding) { buildBubbleBarToHandleAnimation() } else { // in this case the bubble bar remains visible so not much to do. once we implement // the flyout we'll update this runnable to hide it. Runnable { bubbleBarFlyoutController.collapseFlyout { onFlyoutRemoved(bubbleView) } animatingBubble = null bubbleStashController.showBubbleBarImmediate() bubbleStashController.updateTaskbarTouchRegion() Loading Loading @@ -370,7 +385,7 @@ constructor( if (animatingBubble?.expand == true) { cancelHideAnimation() } else { moveToState(AnimatingBubble.State.IN) setupAndShowFlyout() } // the bubble bar is now fully settled in. update taskbar touch region so it's touchable bubbleStashController.updateTaskbarTouchRegion() Loading @@ -384,8 +399,10 @@ constructor( val bubbleView = b.view val animator = PhysicsAnimator.getInstance(bubbleView) if (animator.isRunning()) animator.cancel() // first bounce the bubble bar and show the flyout. Then hide the flyout. val showAnimation = buildBubbleBarBounceAnimation() val hideAnimation = Runnable { bubbleBarFlyoutController.collapseFlyout { onFlyoutRemoved(bubbleView) } animatingBubble = null bubbleStashController.showBubbleBarImmediate() bubbleStashController.updateTaskbarTouchRegion() Loading Loading @@ -413,7 +430,7 @@ constructor( expandBubbleBar() cancelHideAnimation() } else { moveToState(AnimatingBubble.State.IN) setupAndShowFlyout() } } Loading @@ -427,10 +444,38 @@ constructor( .start() } private fun setupAndShowFlyout() { val bubbleView = animatingBubble?.bubbleView 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() } } else { moveToState(AnimatingBubble.State.IN) } } private fun cancelFlyout() { val bubbleView = animatingBubble?.bubbleView bubbleBarFlyoutController.cancelFlyout { onFlyoutRemoved(bubbleView) } } private fun onFlyoutRemoved(bubbleView: BubbleView?) { bubbleView?.suppressDotForBubbleUpdate(false) bubbleStashController.updateTaskbarTouchRegion() } /** Handles touching the animating bubble bar. */ fun onBubbleBarTouchedWhileAnimating() { PhysicsAnimator.getInstance(bubbleBarView).cancelIfRunning() bubbleStashController.getStashedHandlePhysicsAnimator().cancelIfRunning() cancelFlyout() val hideAnimation = animatingBubble?.hideAnimation ?: return scheduler.cancel(hideAnimation) bubbleBarView.relativePivotY = 1f Loading @@ -439,6 +484,7 @@ constructor( /** Notifies the animator that the taskbar area was touched during an animation. */ fun onStashStateChangingWhileAnimating() { cancelFlyout() val hideAnimation = animatingBubble?.hideAnimation ?: return scheduler.cancel(hideAnimation) animatingBubble = null Loading @@ -446,7 +492,7 @@ constructor( bubbleBarView.relativePivotY = 1f bubbleStashController.onNewBubbleAnimationInterrupted( /* isStashed= */ bubbleBarView.alpha == 0f, bubbleBarView.translationY bubbleBarView.translationY, ) } Loading @@ -455,6 +501,7 @@ constructor( this.animatingBubble = animatingBubble.copy(expand = true) // if we're fully in and waiting to hide, cancel the hide animation and clean up if (animatingBubble.state == AnimatingBubble.State.IN) { cancelFlyout() expandBubbleBar() cancelHideAnimation() } Loading Loading
quickstep/res/values/ids.xml +2 −0 Original line number Diff line number Diff line Loading @@ -19,4 +19,6 @@ <item type="id" name="action_move_left" /> <item type="id" name="action_move_right" /> <item type="id" name="action_dismiss_all" /> <item type="id" name="bubble_bar_flyout_view" /> </resources> No newline at end of file
quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarController.java +0 −2 Original line number Diff line number Diff line Loading @@ -377,8 +377,6 @@ public class BubbleBarController extends IBubblesListener.Stub { // Updates mean the dot state may have changed; any other changes were updated in // the populateBubble step. BubbleBarBubble bb = mBubbles.get(update.updatedBubble.getKey()); // If we're not stashed, we're visible so animate bb.getView().updateDotVisibility(!mBubbleStashController.isStashed() /* animate */); mBubbleBarViewController.animateBubbleNotification( bb, /* isExpanding= */ false, /* isUpdate= */ true); } Loading
quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java +9 −4 Original line number Diff line number Diff line Loading @@ -148,7 +148,8 @@ public class BubbleBarViewController { mBubbleBarFlyoutController = new BubbleBarFlyoutController( mBubbleBarContainer, createFlyoutPositioner(), createFlyoutTopBoundaryListener()); mBubbleBarViewAnimator = new BubbleBarViewAnimator( mBarView, mBubbleStashController, mBubbleBarController::showExpandedView); mBarView, mBubbleStashController, mBubbleBarFlyoutController, mBubbleBarController::showExpandedView); mTaskbarViewPropertiesProvider = taskbarViewPropertiesProvider; onBubbleBarConfigurationChanged(/* animate= */ false); mActivity.addOnDeviceProfileChangeListener( Loading Loading @@ -781,6 +782,11 @@ public class BubbleBarViewController { /** 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 (isExpanded()) { bubble.getView().updateDotVisibility(/* animate= */ true); return; } boolean isInApp = mTaskbarStashController.isInApp(); // if this is the first bubble, animate to the initial state. if (mBarView.getBubbleChildCount() == 1 && !isUpdate) { Loading @@ -789,13 +795,12 @@ public class BubbleBarViewController { } boolean persistentTaskbarOrOnHome = mBubbleStashController.isBubblesShowingOnHome() || !mBubbleStashController.isTransientTaskBar(); if (persistentTaskbarOrOnHome && !isExpanded()) { if (persistentTaskbarOrOnHome) { mBubbleBarViewAnimator.animateBubbleBarForCollapsed(bubble, isExpanding); return; } // only animate the new bubble if we're in an app, have handle view and not auto expanding if (isInApp && mBubbleStashController.getHasHandleView() && !isExpanded()) { if (isInApp && mBubbleStashController.getHasHandleView()) { mBubbleBarViewAnimator.animateBubbleInForStashed(bubble, isExpanding); } } Loading
quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java +1 −1 Original line number Diff line number Diff line Loading @@ -301,7 +301,7 @@ public class BubbleView extends ConstraintLayout { void updateDotVisibility(boolean animate) { if (mDotSuppressedForBubbleUpdate) { // if the dot is suppressed for // if the dot is suppressed for an update, there's nothing to do return; } final float targetScale = hasUnseenContent() ? 1f : 0f; Loading
quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt +63 −16 Original line number Diff line number Diff line Loading @@ -27,6 +27,8 @@ import com.android.launcher3.R import com.android.launcher3.taskbar.bubbles.BubbleBarBubble import com.android.launcher3.taskbar.bubbles.BubbleBarView import com.android.launcher3.taskbar.bubbles.BubbleView import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutController import com.android.launcher3.taskbar.bubbles.flyout.BubbleBarFlyoutMessage import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController import com.android.wm.shell.shared.animation.PhysicsAnimator Loading @@ -36,8 +38,9 @@ class BubbleBarViewAnimator constructor( private val bubbleBarView: BubbleBarView, private val bubbleStashController: BubbleStashController, private val bubbleBarFlyoutController: BubbleBarFlyoutController, private val onExpanded: Runnable, private val scheduler: Scheduler = HandlerScheduler(bubbleBarView) private val scheduler: Scheduler = HandlerScheduler(bubbleBarView), ) { private var animatingBubble: AnimatingBubble? = null Loading @@ -54,7 +57,7 @@ constructor( private companion object { /** The time to show the flyout. */ const val FLYOUT_DELAY_MS: Long = 2500 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. */ Loading @@ -69,7 +72,7 @@ constructor( val showAnimation: Runnable, val hideAnimation: Runnable, val expand: Boolean, val state: State = State.CREATED val state: State = State.CREATED, ) { /** Loading @@ -91,7 +94,7 @@ constructor( /** The bubble notification is now fully showing and waiting to be hidden. */ IN, /** The bubble notification is animating out. */ ANIMATING_OUT ANIMATING_OUT, } } Loading Loading @@ -127,7 +130,7 @@ constructor( private val springConfig = PhysicsAnimator.SpringConfig( stiffness = SpringForce.STIFFNESS_LOW, dampingRatio = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY dampingRatio = SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY, ) /** Animates a bubble for the state where the bubble bar is stashed. */ Loading @@ -137,8 +140,9 @@ constructor( val bubbleView = b.view val animator = PhysicsAnimator.getInstance(bubbleView) if (animator.isRunning()) animator.cancel() // the animation of a new bubble is divided into 2 parts. The first part shows the bubble // and the second part hides it after a delay. // the animation of a new bubble is divided into 2 parts. The first part transforms the // handle to the bubble bar and then shows the flyout. The second part hides the flyout and // transforms the bubble bar back to the handle. val showAnimation = buildHandleToBubbleBarAnimation() val hideAnimation = if (isExpanding) Runnable {} else buildBubbleBarToHandleAnimation() animatingBubble = Loading Loading @@ -243,7 +247,8 @@ constructor( cancelHideAnimation() return@addEndListener } moveToState(AnimatingBubble.State.IN) setupAndShowFlyout() // the bubble bar is now fully settled in. update taskbar touch region so it's touchable bubbleStashController.updateTaskbarTouchRegion() } Loading Loading @@ -316,8 +321,18 @@ constructor( bubbleBarView.scaleY = 1f bubbleStashController.updateTaskbarTouchRegion() } val bubble = animatingBubble?.bubbleView?.bubble as? BubbleBarBubble val flyout = bubble?.flyoutMessage if (flyout != null) { bubbleBarFlyoutController.collapseFlyout { onFlyoutRemoved(bubble.view) animator.start() } } else { animator.start() } } /** Animates to the initial state of the bubble bar, when there are no previous bubbles. */ fun animateToInitialState(b: BubbleBarBubble, isInApp: Boolean, isExpanding: Boolean) { Loading @@ -326,16 +341,16 @@ constructor( val bubbleView = b.view val animator = PhysicsAnimator.getInstance(bubbleView) if (animator.isRunning()) animator.cancel() // the animation of a new bubble is divided into 2 parts. The first part shows the bubble // and the second part hides it after a delay if we are in an app. // the animation of a new bubble is divided into 2 parts. The first part slides in the // bubble bar and shows the flyout. The second part hides the flyout and transforms the // bubble bar to the handle if we're in an app. val showAnimation = buildBubbleBarSpringInAnimation() val hideAnimation = if (isInApp && !isExpanding) { buildBubbleBarToHandleAnimation() } else { // in this case the bubble bar remains visible so not much to do. once we implement // the flyout we'll update this runnable to hide it. Runnable { bubbleBarFlyoutController.collapseFlyout { onFlyoutRemoved(bubbleView) } animatingBubble = null bubbleStashController.showBubbleBarImmediate() bubbleStashController.updateTaskbarTouchRegion() Loading Loading @@ -370,7 +385,7 @@ constructor( if (animatingBubble?.expand == true) { cancelHideAnimation() } else { moveToState(AnimatingBubble.State.IN) setupAndShowFlyout() } // the bubble bar is now fully settled in. update taskbar touch region so it's touchable bubbleStashController.updateTaskbarTouchRegion() Loading @@ -384,8 +399,10 @@ constructor( val bubbleView = b.view val animator = PhysicsAnimator.getInstance(bubbleView) if (animator.isRunning()) animator.cancel() // first bounce the bubble bar and show the flyout. Then hide the flyout. val showAnimation = buildBubbleBarBounceAnimation() val hideAnimation = Runnable { bubbleBarFlyoutController.collapseFlyout { onFlyoutRemoved(bubbleView) } animatingBubble = null bubbleStashController.showBubbleBarImmediate() bubbleStashController.updateTaskbarTouchRegion() Loading Loading @@ -413,7 +430,7 @@ constructor( expandBubbleBar() cancelHideAnimation() } else { moveToState(AnimatingBubble.State.IN) setupAndShowFlyout() } } Loading @@ -427,10 +444,38 @@ constructor( .start() } private fun setupAndShowFlyout() { val bubbleView = animatingBubble?.bubbleView 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() } } else { moveToState(AnimatingBubble.State.IN) } } private fun cancelFlyout() { val bubbleView = animatingBubble?.bubbleView bubbleBarFlyoutController.cancelFlyout { onFlyoutRemoved(bubbleView) } } private fun onFlyoutRemoved(bubbleView: BubbleView?) { bubbleView?.suppressDotForBubbleUpdate(false) bubbleStashController.updateTaskbarTouchRegion() } /** Handles touching the animating bubble bar. */ fun onBubbleBarTouchedWhileAnimating() { PhysicsAnimator.getInstance(bubbleBarView).cancelIfRunning() bubbleStashController.getStashedHandlePhysicsAnimator().cancelIfRunning() cancelFlyout() val hideAnimation = animatingBubble?.hideAnimation ?: return scheduler.cancel(hideAnimation) bubbleBarView.relativePivotY = 1f Loading @@ -439,6 +484,7 @@ constructor( /** Notifies the animator that the taskbar area was touched during an animation. */ fun onStashStateChangingWhileAnimating() { cancelFlyout() val hideAnimation = animatingBubble?.hideAnimation ?: return scheduler.cancel(hideAnimation) animatingBubble = null Loading @@ -446,7 +492,7 @@ constructor( bubbleBarView.relativePivotY = 1f bubbleStashController.onNewBubbleAnimationInterrupted( /* isStashed= */ bubbleBarView.alpha == 0f, bubbleBarView.translationY bubbleBarView.translationY, ) } Loading @@ -455,6 +501,7 @@ constructor( this.animatingBubble = animatingBubble.copy(expand = true) // if we're fully in and waiting to hide, cancel the hide animation and clean up if (animatingBubble.state == AnimatingBubble.State.IN) { cancelFlyout() expandBubbleBar() cancelHideAnimation() } Loading