Loading quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarSwipeController.kt +69 −26 Original line number Diff line number Diff line Loading @@ -21,10 +21,15 @@ import android.content.Context import androidx.annotation.VisibleForTesting import androidx.core.animation.doOnEnd import androidx.dynamicanimation.animation.SpringForce import com.android.launcher3.R import com.android.launcher3.anim.AnimatedFloat import com.android.launcher3.anim.SpringAnimationBuilder import com.android.launcher3.taskbar.TaskbarActivityContext import com.android.launcher3.taskbar.TaskbarThresholdUtils import com.android.launcher3.taskbar.bubbles.BubbleBarSwipeController.StartState.COLLAPSED import com.android.launcher3.taskbar.bubbles.BubbleBarSwipeController.StartState.EXPANDED import com.android.launcher3.taskbar.bubbles.BubbleBarSwipeController.StartState.STASHED import com.android.launcher3.taskbar.bubbles.BubbleBarSwipeController.StartState.UNKNOWN import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController import com.android.launcher3.touch.OverScroll Loading @@ -34,8 +39,8 @@ class BubbleBarSwipeController { private val context: Context private var bubbleStashedHandleViewController: BubbleStashedHandleViewController? = null private var bubbleBarViewController: BubbleBarViewController? = null private var bubbleStashController: BubbleStashController? = null private lateinit var bubbleBarViewController: BubbleBarViewController private lateinit var bubbleStashController: BubbleStashController private var springAnimation: ValueAnimator? = null private val animatedSwipeTranslation = AnimatedFloat(this::onSwipeUpdate) Loading @@ -43,6 +48,7 @@ class BubbleBarSwipeController { private val unstashThreshold: Int private val expandThreshold: Int private val maxOverscroll: Int private val stashThreshold: Int private var swipeState: SwipeState = SwipeState() Loading @@ -54,6 +60,7 @@ class BubbleBarSwipeController { unstashThreshold = dimensionProvider.unstashThreshold expandThreshold = dimensionProvider.expandThreshold maxOverscroll = dimensionProvider.maxOverscroll stashThreshold = dimensionProvider.stashThreshold } fun init(bubbleControllers: BubbleControllers) { Loading @@ -66,23 +73,21 @@ class BubbleBarSwipeController { /** Start tracking a new swipe gesture */ fun start() { if (springAnimation != null) reset() val stashed = bubbleStashController?.isStashed ?: false val barVisible = bubbleStashController?.isBubbleBarVisible() ?: false val expanded = bubbleBarViewController?.isExpanded ?: false swipeState = SwipeState( stashedOnStart = stashed, collapsedOnStart = !stashed && barVisible && !expanded, expandedOnStart = expanded, ) val startState = when { bubbleStashController.isStashed -> STASHED bubbleBarViewController.isExpanded -> EXPANDED bubbleStashController.isBubbleBarVisible() -> COLLAPSED else -> UNKNOWN } swipeState = SwipeState(startState = startState) } /** Update swipe distance to [dy] */ fun swipeTo(dy: Float) { // Only handle swipe up and stashed or collapsed bar if (dy > 0 || swipeState.expandedOnStart) return if (!canHandleSwipe(dy)) { return } animatedSwipeTranslation.updateValue(dy) val prevState = swipeState Loading @@ -90,38 +95,63 @@ class BubbleBarSwipeController { val passedUnstashThreshold = isUnstash(dy) || prevState.passedUnstashThreshold // Expand happens at the end of the gesture, always keep the current value val passedExpandThreshold = isExpand(dy) // Stash happens at the end of the gesture, always keep the current value val passedStashThreshold = isStash(dy) if ( passedUnstashThreshold != prevState.passedUnstashThreshold || passedExpandThreshold != prevState.passedExpandThreshold passedExpandThreshold != prevState.passedExpandThreshold || passedStashThreshold != prevState.passedStashThreshold ) { swipeState = swipeState.copy( passedUnstashThreshold = passedUnstashThreshold, passedExpandThreshold = passedExpandThreshold, passedStashThreshold = passedStashThreshold, ) } if ( swipeState.stashedOnStart && swipeState.startState == STASHED && swipeState.passedUnstashThreshold && !prevState.passedUnstashThreshold ) { bubbleStashController?.showBubbleBar(expandBubbles = false) bubbleStashController.showBubbleBar(expandBubbles = false) } } /** Finish tracking swipe gesture. Animate views back to resting state */ fun finish() { if (swipeState.passedExpandThreshold) { bubbleStashController?.showBubbleBar(expandBubbles = true) when { swipeState.passedExpandThreshold && swipeState.startState in setOf(STASHED, COLLAPSED) -> { bubbleStashController.showBubbleBar(expandBubbles = true) } swipeState.passedStashThreshold && swipeState.startState == COLLAPSED -> { bubbleStashController.stashBubbleBar() } } if (animatedSwipeTranslation.value == 0f) { reset() } else { springToRest() } } /** Returns `true` if we are tracking a swipe gesture */ fun isSwipeGesture(): Boolean { return swipeState.passedUnstashThreshold || swipeState.passedExpandThreshold return swipeState.passedUnstashThreshold || swipeState.passedExpandThreshold || swipeState.passedStashThreshold } private fun canHandleSwipe(dy: Float): Boolean { return when (swipeState.startState) { STASHED -> dy < 0 // stashed bar only handles swipe up COLLAPSED -> true // collapsed bar can be swiped in either direction UNKNOWN, EXPANDED -> false // expanded bar can't be swiped } } private fun isUnstash(dy: Float): Boolean { Loading @@ -132,6 +162,10 @@ class BubbleBarSwipeController { return dy < -expandThreshold } private fun isStash(dy: Float): Boolean { return dy > stashThreshold } private fun reset() { springAnimation?.let { if (it.isRunning) { Loading @@ -147,7 +181,7 @@ class BubbleBarSwipeController { private fun onSwipeUpdate(value: Float) { val dampedSwipe = -OverScroll.dampedScroll(-value, maxOverscroll).toFloat() bubbleStashedHandleViewController?.setTranslationYForSwipe(dampedSwipe) bubbleBarViewController?.setTranslationYForSwipe(dampedSwipe) bubbleBarViewController.setTranslationYForSwipe(dampedSwipe) } private fun springToRest() { Loading @@ -163,19 +197,26 @@ class BubbleBarSwipeController { } internal data class SwipeState( val stashedOnStart: Boolean = false, val collapsedOnStart: Boolean = false, val expandedOnStart: Boolean = false, val startState: StartState = UNKNOWN, val passedUnstashThreshold: Boolean = false, val passedExpandThreshold: Boolean = false, val passedStashThreshold: Boolean = false, ) internal enum class StartState { UNKNOWN, STASHED, COLLAPSED, EXPANDED, } /** Allows overriding the dimension provider for testing */ @VisibleForTesting interface DimensionProvider { val unstashThreshold: Int val expandThreshold: Int val maxOverscroll: Int val stashThreshold: Int } private class DefaultDimensionProvider(taskbarActivityContext: TaskbarActivityContext) : Loading @@ -183,6 +224,7 @@ class BubbleBarSwipeController { override val unstashThreshold: Int override val expandThreshold: Int override val maxOverscroll: Int override val stashThreshold: Int init { val resources = taskbarActivityContext.resources Loading @@ -198,6 +240,7 @@ class BubbleBarSwipeController { taskbarActivityContext.deviceProfile, ) maxOverscroll = taskbarActivityContext.deviceProfile.heightPx - unstashThreshold stashThreshold = resources.getDimensionPixelSize(R.dimen.taskbar_to_nav_threshold) } } } quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/BubbleBarSwipeControllerTest.kt +99 −10 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController import com.android.launcher3.touch.OverScroll import com.google.common.truth.Truth.assertThat import java.util.Optional import kotlin.math.abs import org.junit.Before import org.junit.Rule import org.junit.Test Loading @@ -46,11 +47,13 @@ class BubbleBarSwipeControllerTest { const val UNSTASH_THRESHOLD = 100 const val EXPAND_THRESHOLD = 200 const val MAX_OVERSCROLL = 300 const val STASH_THRESHOLD = 50 const val UP_BELOW_UNSTASH = -UNSTASH_THRESHOLD + 10f const val UP_ABOVE_UNSTASH = -UNSTASH_THRESHOLD - 10f const val UP_ABOVE_EXPAND = -EXPAND_THRESHOLD - 10f const val DOWN_BELOW_UNSTASH = UNSTASH_THRESHOLD + 10f const val DOWN_UNDER_STASH = STASH_THRESHOLD - 10f const val DOWN_OVER_STASH = STASH_THRESHOLD + 10f } private val context = ApplicationProvider.getApplicationContext<Context>() Loading Loading @@ -82,6 +85,9 @@ class BubbleBarSwipeControllerTest { override val maxOverscroll: Int get() = MAX_OVERSCROLL override val stashThreshold: Int get() = STASH_THRESHOLD } bubbleBarSwipeController = BubbleBarSwipeController(context, dimensionProvider) Loading @@ -102,8 +108,12 @@ class BubbleBarSwipeControllerTest { bubbleBarSwipeController.init(bubbleControllers) } // region Test that views have damped translation on swipe private fun testViewsHaveDampedTranslationOnSwipe(swipe: Float) { val dampedTranslation = -OverScroll.dampedScroll(-swipe, MAX_OVERSCROLL).toFloat() val isUp = swipe < 0 val damped = OverScroll.dampedScroll(abs(swipe), MAX_OVERSCROLL).toFloat() val dampedTranslation = if (isUp) -damped else damped getInstrumentation().runOnMainSync { bubbleBarSwipeController.start() bubbleBarSwipeController.swipeTo(swipe) Loading Loading @@ -142,6 +152,22 @@ class BubbleBarSwipeControllerTest { testViewsHaveDampedTranslationOnSwipe(UP_ABOVE_EXPAND) } @Test fun swipeDown_collapsedBar_belowStashThreshold_viewsHaveDampedTranslation() { setUpCollapsedBar() testViewsHaveDampedTranslationOnSwipe(DOWN_UNDER_STASH) } @Test fun swipeDown_collapsedBar_overStashThreshold_viewsHaveDampedTranslation() { setUpCollapsedBar() testViewsHaveDampedTranslationOnSwipe(DOWN_OVER_STASH) } // endregion // region Test that translation on views is reset on finish private fun testViewsTranslationResetOnFinish(swipe: Float) { getInstrumentation().runOnMainSync { bubbleBarSwipeController.start() Loading Loading @@ -194,6 +220,16 @@ class BubbleBarSwipeControllerTest { testViewsTranslationResetOnFinish(UP_ABOVE_EXPAND) } @Test fun swipeDown_collapsedBar_aboveStashThreshold_animateTranslationToZeroOnFinish() { setUpCollapsedBar() testViewsTranslationResetOnFinish(DOWN_OVER_STASH) } // endregion // region Test swipe interactions on stashed bar @Test fun swipeUp_stashedBar_belowUnstashThreshold_doesNotShowBar() { setUpStashedBar() Loading Loading @@ -282,31 +318,84 @@ class BubbleBarSwipeControllerTest { } @Test fun swipeUp_expandedBar_swipeIgnored() { setUpExpandedBar() fun swipeDown_stashedBar_swipeIgnored() { setUpStashedBar() getInstrumentation().runOnMainSync { bubbleBarSwipeController.start() bubbleBarSwipeController.swipeTo(UP_ABOVE_EXPAND) bubbleBarSwipeController.swipeTo(DOWN_BELOW_UNSTASH) bubbleBarSwipeController.finish() bubbleBarSwipeController.swipeTo(DOWN_OVER_STASH) } verify(bubbleStashedHandleViewController, never()).setTranslationYForSwipe(any()) verify(bubbleBarViewController, never()).setTranslationYForSwipe(any()) verify(bubbleStashController, never()).showBubbleBar(any()) } // endregion // region Test swipe interactions on expanded bar @Test fun swipeDown_stashedBar_swipeIgnored() { setUpStashedBar() fun swipe_expandedBar_swipeIgnored() { setUpExpandedBar() getInstrumentation().runOnMainSync { bubbleBarSwipeController.start() bubbleBarSwipeController.swipeTo(DOWN_BELOW_UNSTASH) bubbleBarSwipeController.swipeTo(UP_ABOVE_EXPAND) bubbleBarSwipeController.swipeTo(DOWN_OVER_STASH) bubbleBarSwipeController.finish() } verify(bubbleStashedHandleViewController, never()).setTranslationYForSwipe(any()) verify(bubbleBarViewController, never()).setTranslationYForSwipe(any()) verify(bubbleStashController, never()).showBubbleBar(any()) } // endregion // region Test swipe interactions on collapsed bar @Test fun swipeDown_collapsedBar_underStashThreshold_doesNotHideBar() { setUpCollapsedBar() getInstrumentation().runOnMainSync { bubbleBarSwipeController.start() bubbleBarSwipeController.swipeTo(DOWN_UNDER_STASH) bubbleBarSwipeController.finish() } verify(bubbleStashController, never()).stashBubbleBar() } @Test fun swipeDown_collapsedBar_overStashThreshold_doesNotHideBarBeforeFinish() { setUpCollapsedBar() getInstrumentation().runOnMainSync { bubbleBarSwipeController.start() bubbleBarSwipeController.swipeTo(DOWN_OVER_STASH) } verify(bubbleStashController, never()).stashBubbleBar() getInstrumentation().runOnMainSync { bubbleBarSwipeController.finish() } verify(bubbleStashController).stashBubbleBar() } @Test fun swipeDown_collapsedBar_underStashThreshold_isSwipeGestureFalse() { setUpCollapsedBar() getInstrumentation().runOnMainSync { bubbleBarSwipeController.start() bubbleBarSwipeController.swipeTo(DOWN_UNDER_STASH) } assertThat(bubbleBarSwipeController.isSwipeGesture()).isFalse() } @Test fun swipeDown_collapsedBar_overStashThreshold_isSwipeGestureTrue() { setUpCollapsedBar() getInstrumentation().runOnMainSync { bubbleBarSwipeController.start() bubbleBarSwipeController.swipeTo(DOWN_OVER_STASH) } assertThat(bubbleBarSwipeController.isSwipeGesture()).isTrue() } // endregion private fun setUpStashedBar() { whenever(bubbleStashController.isStashed).thenReturn(true) whenever(bubbleStashController.isBubbleBarVisible()).thenReturn(false) Loading Loading
quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarSwipeController.kt +69 −26 Original line number Diff line number Diff line Loading @@ -21,10 +21,15 @@ import android.content.Context import androidx.annotation.VisibleForTesting import androidx.core.animation.doOnEnd import androidx.dynamicanimation.animation.SpringForce import com.android.launcher3.R import com.android.launcher3.anim.AnimatedFloat import com.android.launcher3.anim.SpringAnimationBuilder import com.android.launcher3.taskbar.TaskbarActivityContext import com.android.launcher3.taskbar.TaskbarThresholdUtils import com.android.launcher3.taskbar.bubbles.BubbleBarSwipeController.StartState.COLLAPSED import com.android.launcher3.taskbar.bubbles.BubbleBarSwipeController.StartState.EXPANDED import com.android.launcher3.taskbar.bubbles.BubbleBarSwipeController.StartState.STASHED import com.android.launcher3.taskbar.bubbles.BubbleBarSwipeController.StartState.UNKNOWN import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController import com.android.launcher3.touch.OverScroll Loading @@ -34,8 +39,8 @@ class BubbleBarSwipeController { private val context: Context private var bubbleStashedHandleViewController: BubbleStashedHandleViewController? = null private var bubbleBarViewController: BubbleBarViewController? = null private var bubbleStashController: BubbleStashController? = null private lateinit var bubbleBarViewController: BubbleBarViewController private lateinit var bubbleStashController: BubbleStashController private var springAnimation: ValueAnimator? = null private val animatedSwipeTranslation = AnimatedFloat(this::onSwipeUpdate) Loading @@ -43,6 +48,7 @@ class BubbleBarSwipeController { private val unstashThreshold: Int private val expandThreshold: Int private val maxOverscroll: Int private val stashThreshold: Int private var swipeState: SwipeState = SwipeState() Loading @@ -54,6 +60,7 @@ class BubbleBarSwipeController { unstashThreshold = dimensionProvider.unstashThreshold expandThreshold = dimensionProvider.expandThreshold maxOverscroll = dimensionProvider.maxOverscroll stashThreshold = dimensionProvider.stashThreshold } fun init(bubbleControllers: BubbleControllers) { Loading @@ -66,23 +73,21 @@ class BubbleBarSwipeController { /** Start tracking a new swipe gesture */ fun start() { if (springAnimation != null) reset() val stashed = bubbleStashController?.isStashed ?: false val barVisible = bubbleStashController?.isBubbleBarVisible() ?: false val expanded = bubbleBarViewController?.isExpanded ?: false swipeState = SwipeState( stashedOnStart = stashed, collapsedOnStart = !stashed && barVisible && !expanded, expandedOnStart = expanded, ) val startState = when { bubbleStashController.isStashed -> STASHED bubbleBarViewController.isExpanded -> EXPANDED bubbleStashController.isBubbleBarVisible() -> COLLAPSED else -> UNKNOWN } swipeState = SwipeState(startState = startState) } /** Update swipe distance to [dy] */ fun swipeTo(dy: Float) { // Only handle swipe up and stashed or collapsed bar if (dy > 0 || swipeState.expandedOnStart) return if (!canHandleSwipe(dy)) { return } animatedSwipeTranslation.updateValue(dy) val prevState = swipeState Loading @@ -90,38 +95,63 @@ class BubbleBarSwipeController { val passedUnstashThreshold = isUnstash(dy) || prevState.passedUnstashThreshold // Expand happens at the end of the gesture, always keep the current value val passedExpandThreshold = isExpand(dy) // Stash happens at the end of the gesture, always keep the current value val passedStashThreshold = isStash(dy) if ( passedUnstashThreshold != prevState.passedUnstashThreshold || passedExpandThreshold != prevState.passedExpandThreshold passedExpandThreshold != prevState.passedExpandThreshold || passedStashThreshold != prevState.passedStashThreshold ) { swipeState = swipeState.copy( passedUnstashThreshold = passedUnstashThreshold, passedExpandThreshold = passedExpandThreshold, passedStashThreshold = passedStashThreshold, ) } if ( swipeState.stashedOnStart && swipeState.startState == STASHED && swipeState.passedUnstashThreshold && !prevState.passedUnstashThreshold ) { bubbleStashController?.showBubbleBar(expandBubbles = false) bubbleStashController.showBubbleBar(expandBubbles = false) } } /** Finish tracking swipe gesture. Animate views back to resting state */ fun finish() { if (swipeState.passedExpandThreshold) { bubbleStashController?.showBubbleBar(expandBubbles = true) when { swipeState.passedExpandThreshold && swipeState.startState in setOf(STASHED, COLLAPSED) -> { bubbleStashController.showBubbleBar(expandBubbles = true) } swipeState.passedStashThreshold && swipeState.startState == COLLAPSED -> { bubbleStashController.stashBubbleBar() } } if (animatedSwipeTranslation.value == 0f) { reset() } else { springToRest() } } /** Returns `true` if we are tracking a swipe gesture */ fun isSwipeGesture(): Boolean { return swipeState.passedUnstashThreshold || swipeState.passedExpandThreshold return swipeState.passedUnstashThreshold || swipeState.passedExpandThreshold || swipeState.passedStashThreshold } private fun canHandleSwipe(dy: Float): Boolean { return when (swipeState.startState) { STASHED -> dy < 0 // stashed bar only handles swipe up COLLAPSED -> true // collapsed bar can be swiped in either direction UNKNOWN, EXPANDED -> false // expanded bar can't be swiped } } private fun isUnstash(dy: Float): Boolean { Loading @@ -132,6 +162,10 @@ class BubbleBarSwipeController { return dy < -expandThreshold } private fun isStash(dy: Float): Boolean { return dy > stashThreshold } private fun reset() { springAnimation?.let { if (it.isRunning) { Loading @@ -147,7 +181,7 @@ class BubbleBarSwipeController { private fun onSwipeUpdate(value: Float) { val dampedSwipe = -OverScroll.dampedScroll(-value, maxOverscroll).toFloat() bubbleStashedHandleViewController?.setTranslationYForSwipe(dampedSwipe) bubbleBarViewController?.setTranslationYForSwipe(dampedSwipe) bubbleBarViewController.setTranslationYForSwipe(dampedSwipe) } private fun springToRest() { Loading @@ -163,19 +197,26 @@ class BubbleBarSwipeController { } internal data class SwipeState( val stashedOnStart: Boolean = false, val collapsedOnStart: Boolean = false, val expandedOnStart: Boolean = false, val startState: StartState = UNKNOWN, val passedUnstashThreshold: Boolean = false, val passedExpandThreshold: Boolean = false, val passedStashThreshold: Boolean = false, ) internal enum class StartState { UNKNOWN, STASHED, COLLAPSED, EXPANDED, } /** Allows overriding the dimension provider for testing */ @VisibleForTesting interface DimensionProvider { val unstashThreshold: Int val expandThreshold: Int val maxOverscroll: Int val stashThreshold: Int } private class DefaultDimensionProvider(taskbarActivityContext: TaskbarActivityContext) : Loading @@ -183,6 +224,7 @@ class BubbleBarSwipeController { override val unstashThreshold: Int override val expandThreshold: Int override val maxOverscroll: Int override val stashThreshold: Int init { val resources = taskbarActivityContext.resources Loading @@ -198,6 +240,7 @@ class BubbleBarSwipeController { taskbarActivityContext.deviceProfile, ) maxOverscroll = taskbarActivityContext.deviceProfile.heightPx - unstashThreshold stashThreshold = resources.getDimensionPixelSize(R.dimen.taskbar_to_nav_threshold) } } }
quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/BubbleBarSwipeControllerTest.kt +99 −10 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController import com.android.launcher3.touch.OverScroll import com.google.common.truth.Truth.assertThat import java.util.Optional import kotlin.math.abs import org.junit.Before import org.junit.Rule import org.junit.Test Loading @@ -46,11 +47,13 @@ class BubbleBarSwipeControllerTest { const val UNSTASH_THRESHOLD = 100 const val EXPAND_THRESHOLD = 200 const val MAX_OVERSCROLL = 300 const val STASH_THRESHOLD = 50 const val UP_BELOW_UNSTASH = -UNSTASH_THRESHOLD + 10f const val UP_ABOVE_UNSTASH = -UNSTASH_THRESHOLD - 10f const val UP_ABOVE_EXPAND = -EXPAND_THRESHOLD - 10f const val DOWN_BELOW_UNSTASH = UNSTASH_THRESHOLD + 10f const val DOWN_UNDER_STASH = STASH_THRESHOLD - 10f const val DOWN_OVER_STASH = STASH_THRESHOLD + 10f } private val context = ApplicationProvider.getApplicationContext<Context>() Loading Loading @@ -82,6 +85,9 @@ class BubbleBarSwipeControllerTest { override val maxOverscroll: Int get() = MAX_OVERSCROLL override val stashThreshold: Int get() = STASH_THRESHOLD } bubbleBarSwipeController = BubbleBarSwipeController(context, dimensionProvider) Loading @@ -102,8 +108,12 @@ class BubbleBarSwipeControllerTest { bubbleBarSwipeController.init(bubbleControllers) } // region Test that views have damped translation on swipe private fun testViewsHaveDampedTranslationOnSwipe(swipe: Float) { val dampedTranslation = -OverScroll.dampedScroll(-swipe, MAX_OVERSCROLL).toFloat() val isUp = swipe < 0 val damped = OverScroll.dampedScroll(abs(swipe), MAX_OVERSCROLL).toFloat() val dampedTranslation = if (isUp) -damped else damped getInstrumentation().runOnMainSync { bubbleBarSwipeController.start() bubbleBarSwipeController.swipeTo(swipe) Loading Loading @@ -142,6 +152,22 @@ class BubbleBarSwipeControllerTest { testViewsHaveDampedTranslationOnSwipe(UP_ABOVE_EXPAND) } @Test fun swipeDown_collapsedBar_belowStashThreshold_viewsHaveDampedTranslation() { setUpCollapsedBar() testViewsHaveDampedTranslationOnSwipe(DOWN_UNDER_STASH) } @Test fun swipeDown_collapsedBar_overStashThreshold_viewsHaveDampedTranslation() { setUpCollapsedBar() testViewsHaveDampedTranslationOnSwipe(DOWN_OVER_STASH) } // endregion // region Test that translation on views is reset on finish private fun testViewsTranslationResetOnFinish(swipe: Float) { getInstrumentation().runOnMainSync { bubbleBarSwipeController.start() Loading Loading @@ -194,6 +220,16 @@ class BubbleBarSwipeControllerTest { testViewsTranslationResetOnFinish(UP_ABOVE_EXPAND) } @Test fun swipeDown_collapsedBar_aboveStashThreshold_animateTranslationToZeroOnFinish() { setUpCollapsedBar() testViewsTranslationResetOnFinish(DOWN_OVER_STASH) } // endregion // region Test swipe interactions on stashed bar @Test fun swipeUp_stashedBar_belowUnstashThreshold_doesNotShowBar() { setUpStashedBar() Loading Loading @@ -282,31 +318,84 @@ class BubbleBarSwipeControllerTest { } @Test fun swipeUp_expandedBar_swipeIgnored() { setUpExpandedBar() fun swipeDown_stashedBar_swipeIgnored() { setUpStashedBar() getInstrumentation().runOnMainSync { bubbleBarSwipeController.start() bubbleBarSwipeController.swipeTo(UP_ABOVE_EXPAND) bubbleBarSwipeController.swipeTo(DOWN_BELOW_UNSTASH) bubbleBarSwipeController.finish() bubbleBarSwipeController.swipeTo(DOWN_OVER_STASH) } verify(bubbleStashedHandleViewController, never()).setTranslationYForSwipe(any()) verify(bubbleBarViewController, never()).setTranslationYForSwipe(any()) verify(bubbleStashController, never()).showBubbleBar(any()) } // endregion // region Test swipe interactions on expanded bar @Test fun swipeDown_stashedBar_swipeIgnored() { setUpStashedBar() fun swipe_expandedBar_swipeIgnored() { setUpExpandedBar() getInstrumentation().runOnMainSync { bubbleBarSwipeController.start() bubbleBarSwipeController.swipeTo(DOWN_BELOW_UNSTASH) bubbleBarSwipeController.swipeTo(UP_ABOVE_EXPAND) bubbleBarSwipeController.swipeTo(DOWN_OVER_STASH) bubbleBarSwipeController.finish() } verify(bubbleStashedHandleViewController, never()).setTranslationYForSwipe(any()) verify(bubbleBarViewController, never()).setTranslationYForSwipe(any()) verify(bubbleStashController, never()).showBubbleBar(any()) } // endregion // region Test swipe interactions on collapsed bar @Test fun swipeDown_collapsedBar_underStashThreshold_doesNotHideBar() { setUpCollapsedBar() getInstrumentation().runOnMainSync { bubbleBarSwipeController.start() bubbleBarSwipeController.swipeTo(DOWN_UNDER_STASH) bubbleBarSwipeController.finish() } verify(bubbleStashController, never()).stashBubbleBar() } @Test fun swipeDown_collapsedBar_overStashThreshold_doesNotHideBarBeforeFinish() { setUpCollapsedBar() getInstrumentation().runOnMainSync { bubbleBarSwipeController.start() bubbleBarSwipeController.swipeTo(DOWN_OVER_STASH) } verify(bubbleStashController, never()).stashBubbleBar() getInstrumentation().runOnMainSync { bubbleBarSwipeController.finish() } verify(bubbleStashController).stashBubbleBar() } @Test fun swipeDown_collapsedBar_underStashThreshold_isSwipeGestureFalse() { setUpCollapsedBar() getInstrumentation().runOnMainSync { bubbleBarSwipeController.start() bubbleBarSwipeController.swipeTo(DOWN_UNDER_STASH) } assertThat(bubbleBarSwipeController.isSwipeGesture()).isFalse() } @Test fun swipeDown_collapsedBar_overStashThreshold_isSwipeGestureTrue() { setUpCollapsedBar() getInstrumentation().runOnMainSync { bubbleBarSwipeController.start() bubbleBarSwipeController.swipeTo(DOWN_OVER_STASH) } assertThat(bubbleBarSwipeController.isSwipeGesture()).isTrue() } // endregion private fun setUpStashedBar() { whenever(bubbleStashController.isStashed).thenReturn(true) whenever(bubbleStashController.isBubbleBarVisible()).thenReturn(false) Loading