Loading packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt +68 −3 Original line number Diff line number Diff line Loading @@ -428,13 +428,78 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() { assertThat(underTest.currentState).isEqualTo(State.PULLING) } @Test fun getDetachDirection_whilePulling_returnsZero() = kosmos.testScope.runTest { // GIVEN a detach threshold val threshold = 100f underTest.onDensityChange( threshold / MagneticNotificationRowManager.MAGNETIC_DETACH_THRESHOLD_DP ) // GIVEN the swiped row is being pulled setTargets() underTest.setMagneticRowTranslation(swipedRow, translation = 100f) // THEN the detach direction is zero val detachDirection = underTest.getDetachDirection(swipedRow) assertThat(detachDirection).isEqualTo(0) } @Test fun getDetachDirection_withoutSwipedRow_returnsZero() = kosmos.testScope.runTest { // GIVEN a detach threshold val threshold = 100f underTest.onDensityChange( threshold / MagneticNotificationRowManager.MAGNETIC_DETACH_THRESHOLD_DP ) // GIVEN the swiped row is being pulled setTargets() underTest.setMagneticRowTranslation(swipedRow, translation = 100f) // THEN the detach direction for a non-swiped row is zero val neighborIndex = childrenNumber / 2 - 1 val neighborRow = children.attachedChildren[neighborIndex] val detachDirection = underTest.getDetachDirection(neighborRow) assertThat(detachDirection).isEqualTo(0) } @Test fun getDetachDirection_whenDetachedToTheRight_returnsCorrectDirection() = kosmos.testScope.runTest { // GIVEN that the swiped row is detached to the right setDetachedState() // THEN the detach direction is 1 val detachDirection = underTest.getDetachDirection(swipedRow) assertThat(detachDirection).isEqualTo(1) } @Test fun getDetachDirection_whenDetachedToTheLeft_returnsCorrectDirection() = kosmos.testScope.runTest { // GIVEN that the swiped row is detached to the left setDetachedState(direction = -1) // THEN the detach direction is -1 val detachDirection = underTest.getDetachDirection(swipedRow) assertThat(detachDirection).isEqualTo(-1) } @After fun tearDown() { // We reset the manager so that all MagneticRowListener can cancel all animations underTest.reset() } private fun setDetachedState() { /** * Set the detached state towards a specific direction: * * 1 -> detached to the right, -1 -> detached to the left */ private fun setDetachedState(direction: Int = 1) { val threshold = 100f underTest.onDensityChange( threshold / MagneticNotificationRowManager.MAGNETIC_DETACH_THRESHOLD_DP Loading @@ -442,10 +507,10 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() { // Set the pulling state setTargets() underTest.setMagneticRowTranslation(swipedRow, translation = 100f) underTest.setMagneticRowTranslation(swipedRow, translation = direction * 100f) // Set a translation that will fall above the threshold val translation = 150f val translation = direction * 150f underTest.setMagneticRowTranslation(swipedRow, translation) assertThat(underTest.currentState).isEqualTo(State.DETACHED) Loading packages/SystemUI/src/com/android/systemui/SwipeHelper.java +17 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,7 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { private static final int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms private static final int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms private static final int MAX_DISMISS_VELOCITY = 4000; // dp/sec private static final int MIN_DISMISS_VELOCITY = 2000; // dp/sec public static final float SWIPE_PROGRESS_FADE_END = 0.6f; // fraction of thumbnail width // beyond which swipe progress->0 Loading Loading @@ -426,6 +427,10 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { public void dismissChild(final View animView, float velocity, final Consumer<Boolean> endAction, long delay, boolean useAccelerateInterpolator, long fixedDuration, boolean isDismissAll) { if (magneticNotificationSwipes()) { int direction = mCallback.getMagneticDetachDirection(animView); velocity = direction * Math.max(getMinDismissVelocity(), Math.abs(velocity)); } final boolean canBeDismissed = mCallback.canChildBeDismissed(animView); float newPos; boolean isLayoutRtl = animView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; Loading Loading @@ -776,6 +781,10 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { return MAX_DISMISS_VELOCITY * mDensityScale; } private float getMinDismissVelocity() { return MIN_DISMISS_VELOCITY * mDensityScale; } protected float getEscapeVelocity() { return getUnscaledEscapeVelocity() * mDensityScale; } Loading Loading @@ -1001,6 +1010,14 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { */ boolean isMagneticViewDismissible(View view, float endVelocity); /** * Get the direction in which a magnetic view was detached. * * @return 1 if detached to the right, -1 if detached to the left, or 0 if the view hasn't * detached or if it is not being swiped magnetically */ int getMagneticDetachDirection(View view); /** * Called when the child is long pressed and available to start drag and drop. * Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManager.kt +11 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,15 @@ interface MagneticNotificationRowManager { */ fun isMagneticRowSwipedDismissible(row: ExpandableNotificationRow, endVelocity: Float): Boolean /** * Query the direction in which the magnetic row was detached. * * @param[row] The magnetic row swiped. * @return 1 if the row was detached towards the right, -1 if detached towards the left, and 0 * if the row hasn't detached yet, or if the row is not being swiped. */ fun getDetachDirection(row: ExpandableNotificationRow): Int /* Reset any roundness that magnetic targets may have */ fun resetRoundness() Loading Loading @@ -159,6 +168,8 @@ interface MagneticNotificationRowManager { endVelocity: Float, ): Boolean = false override fun getDetachDirection(row: ExpandableNotificationRow): Int = 0 override fun resetRoundness() {} override fun reset() {} Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt +7 −0 Original line number Diff line number Diff line Loading @@ -406,6 +406,13 @@ constructor( } } override fun getDetachDirection(row: ExpandableNotificationRow): Int = if (row.isSwipedTarget()) { detachDirectionEstimator.direction.toInt() } else { 0 } override fun resetRoundness() = notificationRoundnessManager.clear() override fun reset() { Loading packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +9 −0 Original line number Diff line number Diff line Loading @@ -521,6 +521,15 @@ public class NotificationStackScrollLayoutController implements Dumpable { } } @Override public int getMagneticDetachDirection(View view) { if (view instanceof ExpandableNotificationRow row) { return mMagneticNotificationRowManager.getDetachDirection(row); } else { return 0; } } @Override public float getTotalTranslationLength(View animView) { return mView.getTotalTranslationLength(animView); Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImplTest.kt +68 −3 Original line number Diff line number Diff line Loading @@ -428,13 +428,78 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() { assertThat(underTest.currentState).isEqualTo(State.PULLING) } @Test fun getDetachDirection_whilePulling_returnsZero() = kosmos.testScope.runTest { // GIVEN a detach threshold val threshold = 100f underTest.onDensityChange( threshold / MagneticNotificationRowManager.MAGNETIC_DETACH_THRESHOLD_DP ) // GIVEN the swiped row is being pulled setTargets() underTest.setMagneticRowTranslation(swipedRow, translation = 100f) // THEN the detach direction is zero val detachDirection = underTest.getDetachDirection(swipedRow) assertThat(detachDirection).isEqualTo(0) } @Test fun getDetachDirection_withoutSwipedRow_returnsZero() = kosmos.testScope.runTest { // GIVEN a detach threshold val threshold = 100f underTest.onDensityChange( threshold / MagneticNotificationRowManager.MAGNETIC_DETACH_THRESHOLD_DP ) // GIVEN the swiped row is being pulled setTargets() underTest.setMagneticRowTranslation(swipedRow, translation = 100f) // THEN the detach direction for a non-swiped row is zero val neighborIndex = childrenNumber / 2 - 1 val neighborRow = children.attachedChildren[neighborIndex] val detachDirection = underTest.getDetachDirection(neighborRow) assertThat(detachDirection).isEqualTo(0) } @Test fun getDetachDirection_whenDetachedToTheRight_returnsCorrectDirection() = kosmos.testScope.runTest { // GIVEN that the swiped row is detached to the right setDetachedState() // THEN the detach direction is 1 val detachDirection = underTest.getDetachDirection(swipedRow) assertThat(detachDirection).isEqualTo(1) } @Test fun getDetachDirection_whenDetachedToTheLeft_returnsCorrectDirection() = kosmos.testScope.runTest { // GIVEN that the swiped row is detached to the left setDetachedState(direction = -1) // THEN the detach direction is -1 val detachDirection = underTest.getDetachDirection(swipedRow) assertThat(detachDirection).isEqualTo(-1) } @After fun tearDown() { // We reset the manager so that all MagneticRowListener can cancel all animations underTest.reset() } private fun setDetachedState() { /** * Set the detached state towards a specific direction: * * 1 -> detached to the right, -1 -> detached to the left */ private fun setDetachedState(direction: Int = 1) { val threshold = 100f underTest.onDensityChange( threshold / MagneticNotificationRowManager.MAGNETIC_DETACH_THRESHOLD_DP Loading @@ -442,10 +507,10 @@ class MagneticNotificationRowManagerImplTest : SysuiTestCase() { // Set the pulling state setTargets() underTest.setMagneticRowTranslation(swipedRow, translation = 100f) underTest.setMagneticRowTranslation(swipedRow, translation = direction * 100f) // Set a translation that will fall above the threshold val translation = 150f val translation = direction * 150f underTest.setMagneticRowTranslation(swipedRow, translation) assertThat(underTest.currentState).isEqualTo(State.DETACHED) Loading
packages/SystemUI/src/com/android/systemui/SwipeHelper.java +17 −0 Original line number Diff line number Diff line Loading @@ -70,6 +70,7 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { private static final int DEFAULT_ESCAPE_ANIMATION_DURATION = 200; // ms private static final int MAX_ESCAPE_ANIMATION_DURATION = 400; // ms private static final int MAX_DISMISS_VELOCITY = 4000; // dp/sec private static final int MIN_DISMISS_VELOCITY = 2000; // dp/sec public static final float SWIPE_PROGRESS_FADE_END = 0.6f; // fraction of thumbnail width // beyond which swipe progress->0 Loading Loading @@ -426,6 +427,10 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { public void dismissChild(final View animView, float velocity, final Consumer<Boolean> endAction, long delay, boolean useAccelerateInterpolator, long fixedDuration, boolean isDismissAll) { if (magneticNotificationSwipes()) { int direction = mCallback.getMagneticDetachDirection(animView); velocity = direction * Math.max(getMinDismissVelocity(), Math.abs(velocity)); } final boolean canBeDismissed = mCallback.canChildBeDismissed(animView); float newPos; boolean isLayoutRtl = animView.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL; Loading Loading @@ -776,6 +781,10 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { return MAX_DISMISS_VELOCITY * mDensityScale; } private float getMinDismissVelocity() { return MIN_DISMISS_VELOCITY * mDensityScale; } protected float getEscapeVelocity() { return getUnscaledEscapeVelocity() * mDensityScale; } Loading Loading @@ -1001,6 +1010,14 @@ public class SwipeHelper implements Gefingerpoken, Dumpable { */ boolean isMagneticViewDismissible(View view, float endVelocity); /** * Get the direction in which a magnetic view was detached. * * @return 1 if detached to the right, -1 if detached to the left, or 0 if the view hasn't * detached or if it is not being swiped magnetically */ int getMagneticDetachDirection(View view); /** * Called when the child is long pressed and available to start drag and drop. * Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManager.kt +11 −0 Original line number Diff line number Diff line Loading @@ -101,6 +101,15 @@ interface MagneticNotificationRowManager { */ fun isMagneticRowSwipedDismissible(row: ExpandableNotificationRow, endVelocity: Float): Boolean /** * Query the direction in which the magnetic row was detached. * * @param[row] The magnetic row swiped. * @return 1 if the row was detached towards the right, -1 if detached towards the left, and 0 * if the row hasn't detached yet, or if the row is not being swiped. */ fun getDetachDirection(row: ExpandableNotificationRow): Int /* Reset any roundness that magnetic targets may have */ fun resetRoundness() Loading Loading @@ -159,6 +168,8 @@ interface MagneticNotificationRowManager { endVelocity: Float, ): Boolean = false override fun getDetachDirection(row: ExpandableNotificationRow): Int = 0 override fun resetRoundness() {} override fun reset() {} Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MagneticNotificationRowManagerImpl.kt +7 −0 Original line number Diff line number Diff line Loading @@ -406,6 +406,13 @@ constructor( } } override fun getDetachDirection(row: ExpandableNotificationRow): Int = if (row.isSwipedTarget()) { detachDirectionEstimator.direction.toInt() } else { 0 } override fun resetRoundness() = notificationRoundnessManager.clear() override fun reset() { Loading
packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +9 −0 Original line number Diff line number Diff line Loading @@ -521,6 +521,15 @@ public class NotificationStackScrollLayoutController implements Dumpable { } } @Override public int getMagneticDetachDirection(View view) { if (view instanceof ExpandableNotificationRow row) { return mMagneticNotificationRowManager.getDetachDirection(row); } else { return 0; } } @Override public float getTotalTranslationLength(View animView) { return mView.getTotalTranslationLength(animView); Loading