From 9eadd68e01cdb9baed2490abb3fbe0e73aca1867 Mon Sep 17 00:00:00 2001 From: Ats Jenk Date: Tue, 3 Sep 2024 14:26:16 -0700 Subject: [PATCH] Align bubble bar stash anim with taskbar (1/n) Only scale bubble bar background during stash and unstash animation. Follows the logic used for taskbar. We scale only the background and clip the icons separately. Bug: 345488489 Test: PersistentBubbleStashControllerTest Test: TransientBubbleStashControllerTest Test: BubbleBarViewAnimatorTest Test: stash and unstash bubble bar in app by swiping up from taskbar Test: expand and collapse bubble bar in app by swiping up on bar Test: expand and collapse bubble bar on home screen by tapping on it Flag: com.android.wm.shell.enable_bubble_bar Change-Id: Ifc7922c444f2179fc49643424815e5e7dde519cc --- .../taskbar/bubbles/BubbleBarBackground.kt | 51 ++++++++++++++++--- .../taskbar/bubbles/BubbleBarView.java | 16 +++++- .../bubbles/BubbleBarViewController.java | 20 ++++++++ .../animation/BubbleBarViewAnimator.kt | 3 ++ .../TransientBubbleStashController.kt | 26 +++++----- .../TransientBubbleStashControllerTest.kt | 6 +-- 6 files changed, 97 insertions(+), 25 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt index 25939e1eb5..f08318e54a 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarBackground.kt @@ -71,6 +71,27 @@ class BubbleBarBackground(context: Context, private var backgroundHeight: Float) } } + /** + * Scale of the background in the x direction. Pivot is at the left edge if [anchorLeft] is + * `true` and at the right edge if it is `false` + */ + var scaleX: Float = 1f + set(value) { + if (field != value) { + field = value + invalidateSelf() + } + } + + /** Scale of the background in the y direction. Pivot is at the bottom edge. */ + var scaleY: Float = 1f + set(value) { + if (field != value) { + field = value + invalidateSelf() + } + } + init { val res = context.resources // configure fill paint @@ -123,13 +144,17 @@ class BubbleBarBackground(context: Context, private var backgroundHeight: Float) ) // Create background path val backgroundPath = Path() - val topOffset = backgroundHeight - bounds.height().toFloat() + val scaledBackgroundHeight = backgroundHeight * scaleY + val scaledWidth = width * scaleX + val topOffset = scaledBackgroundHeight - bounds.height().toFloat() val radius = backgroundHeight / 2f - val left = bounds.left + (if (anchorLeft) 0f else bounds.width().toFloat() - width) - val right = bounds.left + (if (anchorLeft) width else bounds.width().toFloat()) - val top = bounds.top - topOffset + arrowVisibleHeight - val bottom = bounds.top + bounds.height().toFloat() + val left = bounds.left + (if (anchorLeft) 0f else bounds.width().toFloat() - scaledWidth) + val right = bounds.left + (if (anchorLeft) scaledWidth else bounds.width().toFloat()) + // Calculate top with scaled heights for background and arrow to align with stash handle + val top = bounds.bottom - scaledBackgroundHeight + getScaledArrowVisibleHeight() + val bottom = bounds.bottom.toFloat() + backgroundPath.addRoundRect(left, top, right, bottom, radius, radius, Path.Direction.CW) addArrowPathIfNeeded(backgroundPath, topOffset) @@ -142,19 +167,20 @@ class BubbleBarBackground(context: Context, private var backgroundHeight: Float) private fun addArrowPathIfNeeded(sourcePath: Path, topOffset: Float) { if (!showingArrow || arrowHeightFraction <= 0) return val arrowPath = Path() + val scaledHeight = getScaledArrowHeight() RoundedArrowDrawable.addDownPointingRoundedTriangleToPath( arrowWidth, - arrowHeight, + scaledHeight, arrowTipRadius, arrowPath ) // flip it horizontally val pathTransform = Matrix() - pathTransform.setRotate(180f, arrowWidth * 0.5f, arrowHeight * 0.5f) + pathTransform.setRotate(180f, arrowWidth * 0.5f, scaledHeight * 0.5f) arrowPath.transform(pathTransform) // shift to arrow position val arrowStart = bounds.left + arrowPositionX - (arrowWidth / 2f) - val arrowTop = (1 - arrowHeightFraction) * arrowVisibleHeight - topOffset + val arrowTop = (1 - arrowHeightFraction) * getScaledArrowVisibleHeight() - topOffset arrowPath.offset(arrowStart, arrowTop) // union with rectangle sourcePath.op(arrowPath, Path.Op.UNION) @@ -183,6 +209,7 @@ class BubbleBarBackground(context: Context, private var backgroundHeight: Float) fun setBackgroundHeight(newHeight: Float) { backgroundHeight = newHeight + invalidateSelf() } /** @@ -199,6 +226,14 @@ class BubbleBarBackground(context: Context, private var backgroundHeight: Float) invalidateSelf() } + private fun getScaledArrowHeight(): Float { + return arrowHeight * scaleY + } + + private fun getScaledArrowVisibleHeight(): Float { + return max(0f, getScaledArrowHeight() - (arrowHeight - arrowVisibleHeight)) + } + companion object { private const val DARK_THEME_STROKE_ALPHA = 51 private const val LIGHT_THEME_STROKE_ALPHA = 41 diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java index 06301c7453..9c6ba8bb6c 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java @@ -305,6 +305,20 @@ public class BubbleBarView extends FrameLayout { } } + /** + * Set scale for bubble bar background in x direction + */ + public void setBackgroundScaleX(float scaleX) { + mBubbleBarBackground.setScaleX(scaleX); + } + + /** + * Set scale for bubble bar background in y direction + */ + public void setBackgroundScaleY(float scaleY) { + mBubbleBarBackground.setScaleY(scaleY); + } + /** * Sets new icon sizes and newBubbleBarPadding between icons and bubble bar borders. * @@ -322,7 +336,7 @@ public class BubbleBarView extends FrameLayout { int childCount = getChildCount(); for (int i = 0; i < childCount; i++) { View childView = getChildAt(i); - childView.setScaleY(mIconScale); + childView.setScaleX(mIconScale); childView.setScaleY(mIconScale); FrameLayout.LayoutParams params = (LayoutParams) childView.getLayoutParams(); params.height = (int) mIconSize; diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java index d9e3406d3a..d0be5ecb8f 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java @@ -82,6 +82,10 @@ public class BubbleBarViewController { private final MultiValueAlpha mBubbleBarAlpha; private final AnimatedFloat mBubbleBarScaleX = new AnimatedFloat(this::updateScaleX); private final AnimatedFloat mBubbleBarScaleY = new AnimatedFloat(this::updateScaleY); + private final AnimatedFloat mBubbleBarBackgroundScaleX = new AnimatedFloat( + this::updateBackgroundScaleX); + private final AnimatedFloat mBubbleBarBackgroundScaleY = new AnimatedFloat( + this::updateBackgroundScaleY); private final AnimatedFloat mBubbleBarTranslationY = new AnimatedFloat( this::updateTranslationY); @@ -266,6 +270,14 @@ public class BubbleBarViewController { return mBubbleBarScaleY; } + public AnimatedFloat getBubbleBarBackgroundScaleX() { + return mBubbleBarBackgroundScaleX; + } + + public AnimatedFloat getBubbleBarBackgroundScaleY() { + return mBubbleBarBackgroundScaleY; + } + public AnimatedFloat getBubbleBarTranslationY() { return mBubbleBarTranslationY; } @@ -535,6 +547,14 @@ public class BubbleBarViewController { mBarView.setScaleY(scale); } + private void updateBackgroundScaleX(float scale) { + mBarView.setBackgroundScaleX(scale); + } + + private void updateBackgroundScaleY(float scale) { + mBarView.setBackgroundScaleY(scale); + } + // // Manipulating the specific bubble views in the bar // 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 99c50f248d..6a955d92a0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimator.kt @@ -169,6 +169,8 @@ constructor( bubbleBarView.translationY = 0f bubbleBarView.scaleX = 1f bubbleBarView.scaleY = BUBBLE_ANIMATION_INITIAL_SCALE_Y + bubbleBarView.setBackgroundScaleX(1f) + bubbleBarView.setBackgroundScaleY(1f) bubbleBarView.relativePivotY = 0.5f // this is the offset between the center of the bubble bar and the center of the stash @@ -311,6 +313,7 @@ constructor( animatingBubble = null if (!canceled) bubbleStashController.stashBubbleBarImmediate() bubbleBarView.relativePivotY = 1f + bubbleBarView.scaleY = 1f bubbleStashController.updateTaskbarTouchRegion() } animator.start() diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt index 1157305d08..0700ab7eb5 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt @@ -67,8 +67,8 @@ class TransientBubbleStashController( // bubble bar properties private lateinit var bubbleBarAlpha: MultiPropertyFactory.MultiProperty private lateinit var bubbleBarTranslationYAnimator: AnimatedFloat - private lateinit var bubbleBarScaleX: AnimatedFloat - private lateinit var bubbleBarScaleY: AnimatedFloat + private lateinit var bubbleBarBackgroundScaleX: AnimatedFloat + private lateinit var bubbleBarBackgroundScaleY: AnimatedFloat private val handleCenterFromScreenBottom = context.resources.getDimensionPixelSize(R.dimen.bubblebar_stashed_size) / 2f @@ -149,8 +149,8 @@ class TransientBubbleStashController( bubbleBarTranslationYAnimator = bubbleBarViewController.bubbleBarTranslationY // bubble bar has only alpha property, getting it at index 0 bubbleBarAlpha = bubbleBarViewController.bubbleBarAlpha.get(/* index= */ 0) - bubbleBarScaleX = bubbleBarViewController.bubbleBarScaleX - bubbleBarScaleY = bubbleBarViewController.bubbleBarScaleY + bubbleBarBackgroundScaleX = bubbleBarViewController.bubbleBarBackgroundScaleX + bubbleBarBackgroundScaleY = bubbleBarViewController.bubbleBarBackgroundScaleY stashedHeight = bubbleStashedHandleViewController?.stashedHeight ?: 0 stashHandleViewAlpha = bubbleStashedHandleViewController?.stashedHandleAlpha?.get(0) } @@ -160,8 +160,8 @@ class TransientBubbleStashController( if (isBubblesShowingOnHome || isBubblesShowingOnOverview) { isStashed = false animatorSet.playTogether( - bubbleBarScaleX.animateToValue(1f), - bubbleBarScaleY.animateToValue(1f), + bubbleBarBackgroundScaleX.animateToValue(1f), + bubbleBarBackgroundScaleY.animateToValue(1f), bubbleBarTranslationYAnimator.animateToValue(bubbleBarTranslationY), bubbleBarAlpha.animateToValue(1f) ) @@ -181,8 +181,8 @@ class TransientBubbleStashController( stashHandleViewAlpha?.value = 0f this.bubbleBarTranslationYAnimator.updateValue(bubbleBarTranslationY) bubbleBarAlpha.setValue(1f) - bubbleBarScaleX.updateValue(1f) - bubbleBarScaleY.updateValue(1f) + bubbleBarBackgroundScaleX.updateValue(1f) + bubbleBarBackgroundScaleY.updateValue(1f) isStashed = false onIsStashedChanged() } @@ -192,8 +192,8 @@ class TransientBubbleStashController( stashHandleViewAlpha?.value = 1f this.bubbleBarTranslationYAnimator.updateValue(getStashTranslation()) bubbleBarAlpha.setValue(0f) - bubbleBarScaleX.updateValue(getStashScaleX()) - bubbleBarScaleY.updateValue(getStashScaleY()) + bubbleBarBackgroundScaleX.updateValue(getStashScaleX()) + bubbleBarBackgroundScaleY.updateValue(getStashScaleY()) isStashed = true onIsStashedChanged() } @@ -259,7 +259,7 @@ class TransientBubbleStashController( override fun getHandleTranslationY(): Float? = bubbleStashedHandleViewController?.translationY private fun getStashTranslation(): Float { - return bubbleBarTranslationY / 2f + return (bubbleBarTranslationY - stashedHeight) / 2f } @VisibleForTesting @@ -366,8 +366,8 @@ class TransientBubbleStashController( val scaleXTarget = if (isStashed) getStashScaleX() else 1f val scaleYTarget = if (isStashed) getStashScaleY() else 1f return AnimatorSet().apply { - play(bubbleBarScaleX.animateToValue(scaleXTarget)) - play(bubbleBarScaleY.animateToValue(scaleYTarget)) + play(bubbleBarBackgroundScaleX.animateToValue(scaleXTarget)) + play(bubbleBarBackgroundScaleY.animateToValue(scaleYTarget)) } } diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt index 262d8da668..a745b666db 100644 --- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt +++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt @@ -60,7 +60,7 @@ class TransientBubbleStashControllerTest { const val TASK_BAR_TRANSLATION_Y = -TASKBAR_BOTTOM_SPACE const val HANDLE_VIEW_WIDTH = 150 const val HANDLE_VIEW_HEIGHT = 4 - const val BUBBLE_BAR_STASHED_TRANSLATION_Y = -2.5f + const val BUBBLE_BAR_STASHED_TRANSLATION_Y = -4.5f } @get:Rule val animatorTestRule: AnimatorTestRule = AnimatorTestRule(this) @@ -302,8 +302,8 @@ class TransientBubbleStashControllerTest { whenever(bubbleBarViewController.hasBubbles()).thenReturn(true) whenever(bubbleBarViewController.bubbleBarTranslationY).thenReturn(barTranslationY) - whenever(bubbleBarViewController.bubbleBarScaleX).thenReturn(barScaleX) - whenever(bubbleBarViewController.bubbleBarScaleY).thenReturn(barScaleY) + whenever(bubbleBarViewController.bubbleBarBackgroundScaleX).thenReturn(barScaleX) + whenever(bubbleBarViewController.bubbleBarBackgroundScaleY).thenReturn(barScaleY) whenever(bubbleBarViewController.bubbleBarAlpha).thenReturn(barAlpha) whenever(bubbleBarViewController.bubbleBarCollapsedWidth).thenReturn(BUBBLE_BAR_WIDTH) whenever(bubbleBarViewController.bubbleBarCollapsedHeight).thenReturn(BUBBLE_BAR_HEIGHT)