From da9e36e4e7af35617f9114f95c96662e412b6fe5 Mon Sep 17 00:00:00 2001 From: Ats Jenk Date: Fri, 30 Aug 2024 10:11:27 -0700 Subject: [PATCH] Scale bubble bar to the width of the handle When animating bubble bar from the stash handle, scale the width to the handle. Bubble bar is already almost the size of the handle, but a small scale is still added. Bug: 345488489 Flag: com.android.wm.shell.enable_bubble_bar Test: atest TransientBubbleStashControllerTest Test: slow animations down and unstash and stash bubble bar, observe that the width of the bubble bar scales down to the handle Change-Id: I54dc228fa41d4d494bfb15e191d2ba563c0970c7 --- .../taskbar/bubbles/BubbleBarView.java | 5 ++- .../bubbles/BubbleBarViewController.java | 21 ++++++++++ .../BubbleStashedHandleViewController.java | 7 ++++ .../TransientBubbleStashController.kt | 38 ++++++++++++++----- .../TransientBubbleStashControllerTest.kt | 32 ++++++++-------- 5 files changed, 77 insertions(+), 26 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java index c458936c80..e45d7000bc 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java @@ -1303,7 +1303,10 @@ public class BubbleBarView extends FrameLayout { return totalIconSize + totalSpace + horizontalPadding; } - private float collapsedWidth() { + /** + * Get width of the bubble bar if it is collapsed + */ + float collapsedWidth() { final int bubbleChildCount = getBubbleChildCount(); final float horizontalPadding = 2 * mBubbleBarPadding; // If there are more than 2 bubbles, the first 2 should be visible when collapsed, diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java index 8b3bb4e736..2c27933665 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java @@ -80,6 +80,7 @@ public class BubbleBarViewController { // These are exposed to {@link BubbleStashController} to animate for stashing/un-stashing private final MultiValueAlpha mBubbleBarAlpha; + private final AnimatedFloat mBubbleBarScaleX = new AnimatedFloat(this::updateScaleX); private final AnimatedFloat mBubbleBarScaleY = new AnimatedFloat(this::updateScaleY); private final AnimatedFloat mBubbleBarTranslationY = new AnimatedFloat( this::updateTranslationY); @@ -257,6 +258,10 @@ public class BubbleBarViewController { return mBubbleBarAlpha; } + public AnimatedFloat getBubbleBarScaleX() { + return mBubbleBarScaleX; + } + public AnimatedFloat getBubbleBarScaleY() { return mBubbleBarScaleY; } @@ -265,6 +270,10 @@ public class BubbleBarViewController { return mBubbleBarTranslationY; } + public float getBubbleBarCollapsedWidth() { + return mBarView.collapsedWidth(); + } + public float getBubbleBarCollapsedHeight() { return mBarView.getBubbleBarCollapsedHeight(); } @@ -309,6 +318,14 @@ public class BubbleBarViewController { return mBarView.getBubbleBarLocation(); } + /** + * @return {@code true} if bubble bar is on the left edge of the screen, {@code false} if on + * the right + */ + public boolean isBubbleBarOnLeft() { + return mBarView.getBubbleBarLocation().isOnLeft(mBarView.isLayoutRtl()); + } + /** * Update bar {@link BubbleBarLocation} */ @@ -510,6 +527,10 @@ public class BubbleBarViewController { + mBubbleBarStashTranslationY); } + private void updateScaleX(float scale) { + mBarView.setScaleX(scale); + } + private void updateScaleY(float scale) { mBarView.setScaleY(scale); } diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java index 5c4428c92d..577a70bf95 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java @@ -172,6 +172,13 @@ public class BubbleStashedHandleViewController { mRegionSamplingHelper = null; } + /** + * Returns the width of the stashed handle. + */ + public int getStashedWidth() { + return mStashedHandleWidth; + } + /** * Returns the height of the stashed handle. */ 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 b8fd1cb1ed..ab27eb206c 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt @@ -67,7 +67,8 @@ class TransientBubbleStashController( // bubble bar properties private lateinit var bubbleBarAlpha: MultiPropertyFactory.MultiProperty private lateinit var bubbleBarTranslationYAnimator: AnimatedFloat - private lateinit var bubbleBarScale: AnimatedFloat + private lateinit var bubbleBarScaleX: AnimatedFloat + private lateinit var bubbleBarScaleY: AnimatedFloat private val handleCenterFromScreenBottom = context.resources.getDimensionPixelSize(R.dimen.bubblebar_stashed_size) / 2f @@ -148,7 +149,8 @@ class TransientBubbleStashController( bubbleBarTranslationYAnimator = bubbleBarViewController.bubbleBarTranslationY // bubble bar has only alpha property, getting it at index 0 bubbleBarAlpha = bubbleBarViewController.bubbleBarAlpha.get(/* index= */ 0) - bubbleBarScale = bubbleBarViewController.bubbleBarScaleY + bubbleBarScaleX = bubbleBarViewController.bubbleBarScaleX + bubbleBarScaleY = bubbleBarViewController.bubbleBarScaleY stashedHeight = bubbleStashedHandleViewController?.stashedHeight ?: 0 stashHandleViewAlpha = bubbleStashedHandleViewController?.stashedHandleAlpha?.get(0) } @@ -158,7 +160,8 @@ class TransientBubbleStashController( if (isBubblesShowingOnHome || isBubblesShowingOnOverview) { isStashed = false animatorSet.playTogether( - bubbleBarScale.animateToValue(1f), + bubbleBarScaleX.animateToValue(1f), + bubbleBarScaleY.animateToValue(1f), bubbleBarTranslationYAnimator.animateToValue(bubbleBarTranslationY), bubbleBarAlpha.animateToValue(1f) ) @@ -178,7 +181,8 @@ class TransientBubbleStashController( stashHandleViewAlpha?.value = 0f this.bubbleBarTranslationYAnimator.updateValue(bubbleBarTranslationY) bubbleBarAlpha.setValue(1f) - bubbleBarScale.updateValue(1f) + bubbleBarScaleX.updateValue(1f) + bubbleBarScaleY.updateValue(1f) isStashed = false onIsStashedChanged() } @@ -188,7 +192,8 @@ class TransientBubbleStashController( stashHandleViewAlpha?.value = 1f this.bubbleBarTranslationYAnimator.updateValue(getStashTranslation()) bubbleBarAlpha.setValue(0f) - bubbleBarScale.updateValue(getStashScale()) + bubbleBarScaleX.updateValue(getStashScaleX()) + bubbleBarScaleY.updateValue(getStashScaleY()) isStashed = true onIsStashedChanged() } @@ -258,7 +263,13 @@ class TransientBubbleStashController( } @VisibleForTesting - fun getStashScale(): Float { + fun getStashScaleX(): Float { + val handleWidth = bubbleStashedHandleViewController?.stashedWidth ?: 0 + return handleWidth / bubbleBarViewController.bubbleBarCollapsedWidth + } + + @VisibleForTesting + fun getStashScaleY(): Float { val handleHeight = bubbleStashedHandleViewController?.stashedHeight ?: 0 return handleHeight / bubbleBarViewController.bubbleBarCollapsedHeight } @@ -298,12 +309,12 @@ class TransientBubbleStashController( } ) - val scaleTarget = if (isStashed) getStashScale() else 1f + val pivotX = if (bubbleBarViewController.isBubbleBarOnLeft) 0f else 1f animatorSet.play( - bubbleBarScale.animateToValue(scaleTarget).apply { + createScaleAnimator(isStashed).apply { this.duration = duration this.interpolator = EMPHASIZED - this.setBubbleBarPivotDuringAnim(0.5f, 1f) + this.setBubbleBarPivotDuringAnim(pivotX, 1f) } ) @@ -351,6 +362,15 @@ class TransientBubbleStashController( .build(translationYDuringStash, AnimatedFloat.VALUE) } + private fun createScaleAnimator(isStashed: Boolean): AnimatorSet { + 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)) + } + } + private fun onIsStashedChanged() { controllersAfterInitAction.runAfterInit { taskbarInsetsController.onTaskbarOrBubblebarWindowHeightOrInsetsChanged() 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 63c21979c2..262d8da668 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 @@ -54,9 +54,11 @@ class TransientBubbleStashControllerTest { companion object { const val TASKBAR_BOTTOM_SPACE = 5 + const val BUBBLE_BAR_WIDTH = 200f const val BUBBLE_BAR_HEIGHT = 100f const val HOTSEAT_TRANSLATION_Y = -45f 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 } @@ -75,7 +77,8 @@ class TransientBubbleStashControllerTest { private lateinit var bubbleBarView: BubbleBarView private lateinit var stashedHandleView: StashedHandleView private lateinit var barTranslationY: AnimatedFloat - private lateinit var barScale: AnimatedFloat + private lateinit var barScaleX: AnimatedFloat + private lateinit var barScaleY: AnimatedFloat private lateinit var barAlpha: MultiValueAlpha private lateinit var stashedHandleAlpha: MultiValueAlpha private lateinit var stashedHandleScale: AnimatedFloat @@ -173,8 +176,8 @@ class TransientBubbleStashControllerTest { assertThat(mTransientBubbleStashController.isStashed).isTrue() assertThat(bubbleBarView.translationY).isEqualTo(BUBBLE_BAR_STASHED_TRANSLATION_Y) assertThat(bubbleBarView.alpha).isEqualTo(0f) - assertThat(bubbleBarView.scaleX).isEqualTo(mTransientBubbleStashController.getStashScale()) - assertThat(bubbleBarView.scaleY).isEqualTo(mTransientBubbleStashController.getStashScale()) + assertThat(bubbleBarView.scaleX).isEqualTo(mTransientBubbleStashController.getStashScaleX()) + assertThat(bubbleBarView.scaleY).isEqualTo(mTransientBubbleStashController.getStashScaleY()) // Handle view is visible assertThat(stashedHandleView.translationY).isEqualTo(0) assertThat(stashedHandleView.alpha).isEqualTo(1) @@ -195,7 +198,7 @@ class TransientBubbleStashControllerTest { // Then assertThat(barTranslationY.isAnimating).isTrue() - assertThat(barScale.isAnimating).isTrue() + assertThat(barScaleX.isAnimating).isTrue() // Wait until animation ends advanceTimeBy(BubbleStashController.BAR_STASH_DURATION) @@ -242,8 +245,8 @@ class TransientBubbleStashControllerTest { // Then all property values are updated assertThat(bubbleBarView.translationY).isEqualTo(BUBBLE_BAR_STASHED_TRANSLATION_Y) assertThat(bubbleBarView.alpha).isEqualTo(0) - assertThat(bubbleBarView.scaleX).isEqualTo(mTransientBubbleStashController.getStashScale()) - assertThat(bubbleBarView.scaleY).isEqualTo(mTransientBubbleStashController.getStashScale()) + assertThat(bubbleBarView.scaleX).isEqualTo(mTransientBubbleStashController.getStashScaleX()) + assertThat(bubbleBarView.scaleY).isEqualTo(mTransientBubbleStashController.getStashScaleY()) // Handle is visible at correct Y position assertThat(stashedHandleView.alpha).isEqualTo(1) assertThat(stashedHandleView.translationY).isEqualTo(0) @@ -293,20 +296,16 @@ class TransientBubbleStashControllerTest { private fun setUpBubbleBarController() { barTranslationY = AnimatedFloat(Runnable { bubbleBarView.translationY = barTranslationY.value }) - barScale = - AnimatedFloat( - Runnable { - val scale: Float = barScale.value - bubbleBarView.scaleX = scale - bubbleBarView.scaleY = scale - } - ) + barScaleX = AnimatedFloat { value -> bubbleBarView.scaleX = value } + barScaleY = AnimatedFloat { value -> bubbleBarView.scaleY = value } barAlpha = MultiValueAlpha(bubbleBarView, 1 /* num alpha channels */) whenever(bubbleBarViewController.hasBubbles()).thenReturn(true) whenever(bubbleBarViewController.bubbleBarTranslationY).thenReturn(barTranslationY) - whenever(bubbleBarViewController.bubbleBarScaleY).thenReturn(barScale) + whenever(bubbleBarViewController.bubbleBarScaleX).thenReturn(barScaleX) + whenever(bubbleBarViewController.bubbleBarScaleY).thenReturn(barScaleY) whenever(bubbleBarViewController.bubbleBarAlpha).thenReturn(barAlpha) + whenever(bubbleBarViewController.bubbleBarCollapsedWidth).thenReturn(BUBBLE_BAR_WIDTH) whenever(bubbleBarViewController.bubbleBarCollapsedHeight).thenReturn(BUBBLE_BAR_HEIGHT) } @@ -316,7 +315,7 @@ class TransientBubbleStashControllerTest { stashedHandleScale = AnimatedFloat( Runnable { - val scale: Float = barScale.value + val scale: Float = barScaleX.value bubbleBarView.scaleX = scale bubbleBarView.scaleY = scale } @@ -326,6 +325,7 @@ class TransientBubbleStashControllerTest { whenever(bubbleStashedHandleViewController.stashedHandleAlpha) .thenReturn(stashedHandleAlpha) whenever(bubbleStashedHandleViewController.physicsAnimator).thenReturn(stashPhysicsAnimator) + whenever(bubbleStashedHandleViewController.stashedWidth).thenReturn(HANDLE_VIEW_WIDTH) whenever(bubbleStashedHandleViewController.stashedHeight).thenReturn(HANDLE_VIEW_HEIGHT) whenever(bubbleStashedHandleViewController.setTranslationYForSwipe(any())).thenAnswer { invocation ->