Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt +36 −1 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() { private val sectionsManager = mock<NotificationSectionsManager>() private val msdlPlayer = kosmos.fakeMSDLPlayer private var canRowBeDismissed = true private var magneticAnimationsCancelled = false private val underTest = kosmos.magneticNotificationRowManagerImpl Loading @@ -64,6 +65,7 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() { children = notificationTestHelper.createGroup(childrenNumber).childrenContainer swipedRow = children.attachedChildren[childrenNumber / 2] configureMagneticRowListener(swipedRow) magneticAnimationsCancelled = false } @Test Loading Loading @@ -247,6 +249,35 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() { assertThat(underTest.currentState).isEqualTo(State.IDLE) } @Test fun onMagneticInteractionEnd_whenDetached_cancelsMagneticAnimations() = kosmos.testScope.runTest { // GIVEN the swiped row is detached setDetachedState() // WHEN the interaction ends on the row underTest.onMagneticInteractionEnd(swipedRow, velocity = null) // THEN magnetic animations are cancelled assertThat(magneticAnimationsCancelled).isTrue() } @Test fun onMagneticInteractionEnd_forMagneticNeighbor_cancelsMagneticAnimations() = kosmos.testScope.runTest { val neighborRow = children.attachedChildren[childrenNumber / 2 - 1] configureMagneticRowListener(neighborRow) // GIVEN that targets are set setTargets() // WHEN the interactionEnd is called on a target different from the swiped row underTest.onMagneticInteractionEnd(neighborRow, null) // THEN magnetic animations are cancelled assertThat(magneticAnimationsCancelled).isTrue() } private fun setDetachedState() { val threshold = 100f underTest.setSwipeThresholdPx(threshold) Loading Loading @@ -284,7 +315,11 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() { startVelocity: Float, ) {} override fun cancelMagneticAnimations() {} override fun cancelMagneticAnimations() { magneticAnimationsCancelled = true } override fun cancelTranslationAnimations() {} override fun canRowBeDismissed(): Boolean = canRowBeDismissed } Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java +3 −3 Original line number Diff line number Diff line Loading @@ -405,7 +405,7 @@ public class NotificationSwipeHelperTest extends SysuiTestCase { doNothing().when(mSwipeHelper).superSnapChild(mNotificationRow, 0, 0); mSwipeHelper.snapChild(mNotificationRow, 0, 0); verify(mCallback, times(1)).onDragCancelledWithVelocity(mNotificationRow, 0); verify(mCallback, times(1)).onDragCancelled(mNotificationRow); verify(mSwipeHelper, times(1)).superSnapChild(mNotificationRow, 0, 0); verify(mSwipeHelper, times(1)).handleMenuCoveredOrDismissed(); } Loading @@ -416,7 +416,7 @@ public class NotificationSwipeHelperTest extends SysuiTestCase { doNothing().when(mSwipeHelper).superSnapChild(mNotificationRow, 10, 0); mSwipeHelper.snapChild(mNotificationRow, 10, 0); verify(mCallback, times(1)).onDragCancelledWithVelocity(mNotificationRow, 0); verify(mCallback, times(1)).onDragCancelled(mNotificationRow); verify(mSwipeHelper, times(1)).superSnapChild(mNotificationRow, 10, 0); verify(mSwipeHelper, times(0)).handleMenuCoveredOrDismissed(); } Loading @@ -426,7 +426,7 @@ public class NotificationSwipeHelperTest extends SysuiTestCase { doNothing().when(mSwipeHelper).superSnapChild(mView, 10, 0); mSwipeHelper.snapChild(mView, 10, 0); verify(mCallback).onDragCancelledWithVelocity(mView, 0); verify(mCallback).onDragCancelled(mView); verify(mSwipeHelper, never()).superSnapChild(mView, 10, 0); } Loading packages/SystemUI/src/com/android/systemui/SwipeHelper.java +16 −7 Original line number Diff line number Diff line Loading @@ -352,6 +352,7 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { && Math.abs(delta) > Math.abs(deltaPerpendicular)) { if (mCallback.canChildBeDragged(mTouchedView)) { mIsSwiping = true; mCallback.setMagneticAndRoundableTargets(mTouchedView); mCallback.onBeginDrag(mTouchedView); mInitialTouchPos = getPos(ev); mTranslation = getTranslation(mTouchedView); Loading Loading @@ -444,6 +445,7 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { }; Animator anim = getViewTranslationAnimator(animView, newPos, updateListener); mCallback.onMagneticInteractionEnd(animView, velocity); if (anim == null) { onDismissChildWithAnimationFinished(); return; Loading Loading @@ -733,7 +735,8 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { dismissChild(mTouchedView, velocity, !swipedFastEnough() /* useAccelerateInterpolator */); } else { mCallback.onDragCancelledWithVelocity(mTouchedView, velocity); mCallback.onMagneticInteractionEnd(mTouchedView, velocity); mCallback.onDragCancelled(mTouchedView); snapChild(mTouchedView, 0 /* leftTarget */, velocity); } mTouchedView = null; Loading Loading @@ -935,18 +938,24 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { void onBeginDrag(View v); /** * Set magnetic and roundable targets for a view. */ void setMagneticAndRoundableTargets(View v); void onChildDismissed(View v); void onDragCancelled(View v); /** * A drag operation has been cancelled on a view with a final velocity. * @param v View that was dragged. * @param finalVelocity Final velocity of the drag. * Notify that a magnetic interaction ended on a view with a velocity. * <p> * This method should be called when a view will snap back or be dismissed. * * @param view The {@link View} whose magnetic interaction ended. * @param velocity The velocity when the interaction ended. */ default void onDragCancelledWithVelocity(View v, float finalVelocity) { onDragCancelled(v); } void onMagneticInteractionEnd(View view, float velocity); /** * Called when the child is long pressed and available to start drag and drop. Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java +6 −2 Original line number Diff line number Diff line Loading @@ -106,7 +106,7 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable, Ro @Override public void triggerMagneticForce(float endTranslation, @NonNull SpringForce springForce, float startVelocity) { cancelMagneticAnimations(); cancelTranslationAnimations(); mMagneticAnimator.setSpring(springForce); mMagneticAnimator.setStartVelocity(startVelocity); mMagneticAnimator.animateToFinalPosition(endTranslation); Loading @@ -114,10 +114,14 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable, Ro @Override public void cancelMagneticAnimations() { cancelTranslationAnimations(); mMagneticAnimator.cancel(); } @Override public void cancelTranslationAnimations() { ExpandableView.this.cancelTranslationAnimations(); } @Override public boolean canRowBeDismissed() { return canExpandableViewBeDismissed(); Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt +22 −11 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ constructor( stackScrollLayout, MAGNETIC_TRANSLATION_MULTIPLIERS.size, ) currentMagneticListeners.swipedListener()?.cancelTranslationAnimations() newListeners.forEach { if (currentMagneticListeners.contains(it)) { it?.cancelMagneticAnimations() Loading Loading @@ -214,22 +215,32 @@ constructor( } override fun onMagneticInteractionEnd(row: ExpandableNotificationRow, velocity: Float?) { if (!row.isSwipedTarget()) return if (row.isSwipedTarget()) { when (currentState) { State.PULLING -> { snapNeighborsBack(velocity) currentState = State.IDLE } State.DETACHED -> { // Cancel any detaching animation that may be occurring currentMagneticListeners.swipedListener()?.cancelMagneticAnimations() currentState = State.IDLE } else -> {} } } else { // A magnetic neighbor may be dismissing. In this case, we need to cancel any snap back // magnetic animation to let the external dismiss animation proceed. val listener = currentMagneticListeners.find { it == row.magneticRowListener } listener?.cancelMagneticAnimations() } } override fun reset() { currentMagneticListeners.forEach { it?.cancelMagneticAnimations() } currentMagneticListeners.forEach { it?.cancelMagneticAnimations() it?.cancelTranslationAnimations() } currentState = State.IDLE currentMagneticListeners = listOf() currentRoundableTargets = null Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt +36 −1 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() { private val sectionsManager = mock<NotificationSectionsManager>() private val msdlPlayer = kosmos.fakeMSDLPlayer private var canRowBeDismissed = true private var magneticAnimationsCancelled = false private val underTest = kosmos.magneticNotificationRowManagerImpl Loading @@ -64,6 +65,7 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() { children = notificationTestHelper.createGroup(childrenNumber).childrenContainer swipedRow = children.attachedChildren[childrenNumber / 2] configureMagneticRowListener(swipedRow) magneticAnimationsCancelled = false } @Test Loading Loading @@ -247,6 +249,35 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() { assertThat(underTest.currentState).isEqualTo(State.IDLE) } @Test fun onMagneticInteractionEnd_whenDetached_cancelsMagneticAnimations() = kosmos.testScope.runTest { // GIVEN the swiped row is detached setDetachedState() // WHEN the interaction ends on the row underTest.onMagneticInteractionEnd(swipedRow, velocity = null) // THEN magnetic animations are cancelled assertThat(magneticAnimationsCancelled).isTrue() } @Test fun onMagneticInteractionEnd_forMagneticNeighbor_cancelsMagneticAnimations() = kosmos.testScope.runTest { val neighborRow = children.attachedChildren[childrenNumber / 2 - 1] configureMagneticRowListener(neighborRow) // GIVEN that targets are set setTargets() // WHEN the interactionEnd is called on a target different from the swiped row underTest.onMagneticInteractionEnd(neighborRow, null) // THEN magnetic animations are cancelled assertThat(magneticAnimationsCancelled).isTrue() } private fun setDetachedState() { val threshold = 100f underTest.setSwipeThresholdPx(threshold) Loading Loading @@ -284,7 +315,11 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() { startVelocity: Float, ) {} override fun cancelMagneticAnimations() {} override fun cancelMagneticAnimations() { magneticAnimationsCancelled = true } override fun cancelTranslationAnimations() {} override fun canRowBeDismissed(): Boolean = canRowBeDismissed } Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/NotificationSwipeHelperTest.java +3 −3 Original line number Diff line number Diff line Loading @@ -405,7 +405,7 @@ public class NotificationSwipeHelperTest extends SysuiTestCase { doNothing().when(mSwipeHelper).superSnapChild(mNotificationRow, 0, 0); mSwipeHelper.snapChild(mNotificationRow, 0, 0); verify(mCallback, times(1)).onDragCancelledWithVelocity(mNotificationRow, 0); verify(mCallback, times(1)).onDragCancelled(mNotificationRow); verify(mSwipeHelper, times(1)).superSnapChild(mNotificationRow, 0, 0); verify(mSwipeHelper, times(1)).handleMenuCoveredOrDismissed(); } Loading @@ -416,7 +416,7 @@ public class NotificationSwipeHelperTest extends SysuiTestCase { doNothing().when(mSwipeHelper).superSnapChild(mNotificationRow, 10, 0); mSwipeHelper.snapChild(mNotificationRow, 10, 0); verify(mCallback, times(1)).onDragCancelledWithVelocity(mNotificationRow, 0); verify(mCallback, times(1)).onDragCancelled(mNotificationRow); verify(mSwipeHelper, times(1)).superSnapChild(mNotificationRow, 10, 0); verify(mSwipeHelper, times(0)).handleMenuCoveredOrDismissed(); } Loading @@ -426,7 +426,7 @@ public class NotificationSwipeHelperTest extends SysuiTestCase { doNothing().when(mSwipeHelper).superSnapChild(mView, 10, 0); mSwipeHelper.snapChild(mView, 10, 0); verify(mCallback).onDragCancelledWithVelocity(mView, 0); verify(mCallback).onDragCancelled(mView); verify(mSwipeHelper, never()).superSnapChild(mView, 10, 0); } Loading
packages/SystemUI/src/com/android/systemui/SwipeHelper.java +16 −7 Original line number Diff line number Diff line Loading @@ -352,6 +352,7 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { && Math.abs(delta) > Math.abs(deltaPerpendicular)) { if (mCallback.canChildBeDragged(mTouchedView)) { mIsSwiping = true; mCallback.setMagneticAndRoundableTargets(mTouchedView); mCallback.onBeginDrag(mTouchedView); mInitialTouchPos = getPos(ev); mTranslation = getTranslation(mTouchedView); Loading Loading @@ -444,6 +445,7 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { }; Animator anim = getViewTranslationAnimator(animView, newPos, updateListener); mCallback.onMagneticInteractionEnd(animView, velocity); if (anim == null) { onDismissChildWithAnimationFinished(); return; Loading Loading @@ -733,7 +735,8 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { dismissChild(mTouchedView, velocity, !swipedFastEnough() /* useAccelerateInterpolator */); } else { mCallback.onDragCancelledWithVelocity(mTouchedView, velocity); mCallback.onMagneticInteractionEnd(mTouchedView, velocity); mCallback.onDragCancelled(mTouchedView); snapChild(mTouchedView, 0 /* leftTarget */, velocity); } mTouchedView = null; Loading Loading @@ -935,18 +938,24 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { void onBeginDrag(View v); /** * Set magnetic and roundable targets for a view. */ void setMagneticAndRoundableTargets(View v); void onChildDismissed(View v); void onDragCancelled(View v); /** * A drag operation has been cancelled on a view with a final velocity. * @param v View that was dragged. * @param finalVelocity Final velocity of the drag. * Notify that a magnetic interaction ended on a view with a velocity. * <p> * This method should be called when a view will snap back or be dismissed. * * @param view The {@link View} whose magnetic interaction ended. * @param velocity The velocity when the interaction ended. */ default void onDragCancelledWithVelocity(View v, float finalVelocity) { onDragCancelled(v); } void onMagneticInteractionEnd(View view, float velocity); /** * Called when the child is long pressed and available to start drag and drop. Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java +6 −2 Original line number Diff line number Diff line Loading @@ -106,7 +106,7 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable, Ro @Override public void triggerMagneticForce(float endTranslation, @NonNull SpringForce springForce, float startVelocity) { cancelMagneticAnimations(); cancelTranslationAnimations(); mMagneticAnimator.setSpring(springForce); mMagneticAnimator.setStartVelocity(startVelocity); mMagneticAnimator.animateToFinalPosition(endTranslation); Loading @@ -114,10 +114,14 @@ public abstract class ExpandableView extends FrameLayout implements Dumpable, Ro @Override public void cancelMagneticAnimations() { cancelTranslationAnimations(); mMagneticAnimator.cancel(); } @Override public void cancelTranslationAnimations() { ExpandableView.this.cancelTranslationAnimations(); } @Override public boolean canRowBeDismissed() { return canExpandableViewBeDismissed(); Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt +22 −11 Original line number Diff line number Diff line Loading @@ -97,6 +97,7 @@ constructor( stackScrollLayout, MAGNETIC_TRANSLATION_MULTIPLIERS.size, ) currentMagneticListeners.swipedListener()?.cancelTranslationAnimations() newListeners.forEach { if (currentMagneticListeners.contains(it)) { it?.cancelMagneticAnimations() Loading Loading @@ -214,22 +215,32 @@ constructor( } override fun onMagneticInteractionEnd(row: ExpandableNotificationRow, velocity: Float?) { if (!row.isSwipedTarget()) return if (row.isSwipedTarget()) { when (currentState) { State.PULLING -> { snapNeighborsBack(velocity) currentState = State.IDLE } State.DETACHED -> { // Cancel any detaching animation that may be occurring currentMagneticListeners.swipedListener()?.cancelMagneticAnimations() currentState = State.IDLE } else -> {} } } else { // A magnetic neighbor may be dismissing. In this case, we need to cancel any snap back // magnetic animation to let the external dismiss animation proceed. val listener = currentMagneticListeners.find { it == row.magneticRowListener } listener?.cancelMagneticAnimations() } } override fun reset() { currentMagneticListeners.forEach { it?.cancelMagneticAnimations() } currentMagneticListeners.forEach { it?.cancelMagneticAnimations() it?.cancelTranslationAnimations() } currentState = State.IDLE currentMagneticListeners = listOf() currentRoundableTargets = null Loading