Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 70bed675 authored by John Li's avatar John Li
Browse files

Haptic effect on swiping the notification item

Haptic once the swiping on the notification item is going to snap in either directions. The snap-in scenario is about the notification item when there is a "snap back point" i.e. if swiping the item back till a certain point it just snaps back to initial state but once it goes past a certain location it snaps into the new location.

- screenshot, https://screenshot.googleplex.com/3NKpocScwk4MRAX

Bug: 175659228
Test: atest SystemUITests:NotificationMenuRowTest
Change-Id: I7ffa4589d84d36050f2e55783c0e2bf2d4384c16
parent f2bda9e3
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.notification.row;

import static android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE;
import static android.view.HapticFeedbackConstants.CLOCK_TICK;

import static com.android.systemui.SwipeHelper.SWIPED_FAR_ENOUGH_SIZE_FRACTION;

@@ -113,6 +114,8 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl

    private boolean mIsUserTouching;

    private boolean mSnappingToDismiss;

    private final PeopleNotificationIdentifier mPeopleNotificationIdentifier;

    public NotificationMenuRow(Context context,
@@ -175,6 +178,11 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
        return mSnapping;
    }

    @VisibleForTesting
    protected boolean isSnappingToDismiss() {
        return mSnappingToDismiss;
    }

    @Override
    public void setMenuClickListener(OnMenuEventListener listener) {
        mMenuListener = listener;
@@ -346,6 +354,14 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
            mCheckForDrag = new CheckForDrag();
            mHandler.postDelayed(mCheckForDrag, SHOW_MENU_DELAY);
        }
        if (canBeDismissed()) {
            final float dismissThreshold = getDismissThreshold();
            final boolean snappingToDismiss = delta < -dismissThreshold || delta > dismissThreshold;
            if (mSnappingToDismiss != snappingToDismiss) {
                getMenuView().performHapticFeedback(CLOCK_TICK);
            }
            mSnappingToDismiss = snappingToDismiss;
        }
    }

    @VisibleForTesting
@@ -362,6 +378,7 @@ public class NotificationMenuRow implements NotificationMenuRowPlugin, View.OnCl
    @Override
    public void onTouchStart() {
        beginDrag();
        mSnappingToDismiss = false;
    }

    @Override
+62 −1
Original line number Diff line number Diff line
@@ -14,8 +14,9 @@

package com.android.systemui.statusbar.notification.row;

import static android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE;
import static android.provider.Settings.Global.SHOW_NEW_NOTIF_DISMISS;
import static android.provider.Settings.Secure.SHOW_NOTIFICATION_SNOOZE;
import static android.view.HapticFeedbackConstants.CLOCK_TICK;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
@@ -33,6 +34,7 @@ import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
import android.testing.ViewUtils;
import android.view.View;
import android.view.ViewGroup;

import androidx.test.filters.SmallTest;
@@ -54,12 +56,14 @@ import org.mockito.Mockito;
public class NotificationMenuRowTest extends LeakCheckedTest {

    private ExpandableNotificationRow mRow;
    private View mView;
    private PeopleNotificationIdentifier mPeopleNotificationIdentifier;

    @Before
    public void setup() {
        injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
        mRow = mock(ExpandableNotificationRow.class);
        mView = mock(View.class);
        mPeopleNotificationIdentifier = mock(PeopleNotificationIdentifier.class);
        NotificationEntry entry = new NotificationEntryBuilder().build();
        when(mRow.getEntry()).thenReturn(entry);
@@ -409,4 +413,61 @@ public class NotificationMenuRowTest extends LeakCheckedTest {
        row.setMenuAlpha(0.5f);
        assertTrue("when alpha is .5, menu is visible", row.isMenuVisible());
    }

    @Test
    public void testOnTouchMove() {
        NotificationMenuRow row = Mockito.spy(
                new NotificationMenuRow(mContext, mPeopleNotificationIdentifier));
        row.createMenu(mRow, null);
        doReturn(50f).when(row).getDismissThreshold();
        doReturn(true).when(row).canBeDismissed();
        doReturn(mView).when(row).getMenuView();
        row.onTouchMove(30f);

        assertFalse("When moving not farther than threshold, menu is not snapping to dismiss",
                row.isSnappingToDismiss());
        verify(mView, times(0)).performHapticFeedback(CLOCK_TICK);

        row.onTouchMove(60f);

        assertTrue("When moving farther than threshold, menu is snapping to dismiss",
                row.isSnappingToDismiss());
        verify(mView, times(1)).performHapticFeedback(CLOCK_TICK);

        row.onTouchMove(70f);

        assertTrue("When moving farther than threshold, menu is snapping to dismiss",
                row.isSnappingToDismiss());
        verify(mView, times(1)).performHapticFeedback(CLOCK_TICK);

        row.onTouchMove(30f);

        assertFalse("When moving not farther than threshold, menu is not snapping to dismiss",
                row.isSnappingToDismiss());
        verify(mView, times(2)).performHapticFeedback(CLOCK_TICK);

        row.onTouchMove(-30f);

        assertFalse("When moving not farther than threshold, menu is not snapping to dismiss",
                row.isSnappingToDismiss());
        verify(mView, times(2)).performHapticFeedback(CLOCK_TICK);

        row.onTouchMove(-60f);

        assertTrue("When moving farther than threshold, menu is snapping to dismiss",
                row.isSnappingToDismiss());
        verify(mView, times(3)).performHapticFeedback(CLOCK_TICK);

        row.onTouchMove(-70f);

        assertTrue("When moving farther than threshold, menu is snapping to dismiss",
                row.isSnappingToDismiss());
        verify(mView, times(3)).performHapticFeedback(CLOCK_TICK);

        row.onTouchMove(-30f);

        assertFalse("When moving not farther than threshold, menu is not snapping to dismiss",
                row.isSnappingToDismiss());
        verify(mView, times(4)).performHapticFeedback(CLOCK_TICK);
    }
}