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

Commit afa5fd51 authored by Juan Sebastian Martinez's avatar Juan Sebastian Martinez
Browse files

Using performHapticFeedback on LockIconViewController

Moving towards new haptics API that triggers haptics directly from the UI thread.
The LockIconViewController can use the new performHapticFeedback method in the events of (DOWN)
HOVER_ENTER and (MOVE) HOVER_MOVE (via LongPress). The haptics for the HOVER_ENTER event use
the CONTEXT_CLICK constant. Consistent with the intended behavior and relation to the
UdfpsController, haptics for the case of a long press (due to HOVER_MOVE) use the LONG_PRESS
constant. The changes are controlled by a feature flag.

Test: Tests were added to the LockIconViewControllerTest class to verify
  the use of old and new vibration methods on the above events.
Bug: 245528624
Change-Id: I6ab402df7339df33b4ee54585478d75ff9ffac40
parent 0ac98182
Loading
Loading
Loading
Loading
+36 −13
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import static com.android.keyguard.LockIconView.ICON_UNLOCK;
import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
import static com.android.systemui.flags.Flags.DOZING_MIGRATION_1;
import static com.android.systemui.flags.Flags.LOCKSCREEN_WALLPAPER_DREAM_ENABLED;
import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION;
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;

import android.content.res.Configuration;
@@ -39,6 +40,7 @@ import android.os.VibrationAttributes;
import android.util.DisplayMetrics;
import android.util.Log;
import android.util.MathUtils;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
@@ -610,12 +612,7 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
            case MotionEvent.ACTION_DOWN:
            case MotionEvent.ACTION_HOVER_ENTER:
                if (!mDownDetected && mAccessibilityManager.isTouchExplorationEnabled()) {
                    mVibrator.vibrate(
                            Process.myUid(),
                            getContext().getOpPackageName(),
                            UdfpsController.EFFECT_CLICK,
                            "lock-icon-down",
                            TOUCH_VIBRATION_ATTRIBUTES);
                    vibrateOnTouchExploration();
                }

                // The pointer that causes ACTION_DOWN is always at index 0.
@@ -696,13 +693,8 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
            mOnGestureDetectedRunnable.run();
        }

        // play device entry haptic (same as biometric success haptic)
        mVibrator.vibrate(
                Process.myUid(),
                getContext().getOpPackageName(),
                UdfpsController.EFFECT_CLICK,
                "lock-screen-lock-icon-longpress",
                TOUCH_VIBRATION_ATTRIBUTES);
        // play device entry haptic (consistent with UDFPS controller longpress)
        vibrateOnLongPress();

        mKeyguardViewController.showPrimaryBouncer(/* scrim */ true);
    }
@@ -750,6 +742,37 @@ public class LockIconViewController extends ViewController<LockIconView> impleme
        });
    }

    @VisibleForTesting
    void vibrateOnTouchExploration() {
        if (mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)) {
            mVibrator.performHapticFeedback(
                    mView,
                    HapticFeedbackConstants.CONTEXT_CLICK
            );
        } else {
            mVibrator.vibrate(
                    Process.myUid(),
                    getContext().getOpPackageName(),
                    UdfpsController.EFFECT_CLICK,
                    "lock-icon-down",
                    TOUCH_VIBRATION_ATTRIBUTES);
        }
    }

    @VisibleForTesting
    void vibrateOnLongPress() {
        if (mFeatureFlags.isEnabled(ONE_WAY_HAPTICS_API_MIGRATION)) {
            mVibrator.performHapticFeedback(mView, UdfpsController.LONG_PRESS);
        } else {
            mVibrator.vibrate(
                    Process.myUid(),
                    getContext().getOpPackageName(),
                    UdfpsController.EFFECT_CLICK,
                    "lock-screen-lock-icon-longpress",
                    TOUCH_VIBRATION_ATTRIBUTES);
        }
    }

    private final AuthController.Callback mAuthControllerCallback = new AuthController.Callback() {
        @Override
        public void onAllAuthenticatorsRegistered(@BiometricAuthenticator.Modality int modality) {
+59 −0
Original line number Diff line number Diff line
@@ -20,7 +20,9 @@ import static android.hardware.biometrics.BiometricAuthenticator.TYPE_FINGERPRIN

import static com.android.keyguard.LockIconView.ICON_LOCK;
import static com.android.keyguard.LockIconView.ICON_UNLOCK;
import static com.android.systemui.flags.Flags.ONE_WAY_HAPTICS_API_MIGRATION;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.eq;
@@ -33,11 +35,13 @@ import android.hardware.biometrics.BiometricSourceType;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.util.Pair;
import android.view.HapticFeedbackConstants;
import android.view.View;

import androidx.test.filters.SmallTest;

import com.android.settingslib.udfps.UdfpsOverlayParams;
import com.android.systemui.biometrics.UdfpsController;
import com.android.systemui.doze.util.BurnInHelperKt;

import org.junit.Test;
@@ -339,4 +343,59 @@ public class LockIconViewControllerTest extends LockIconViewControllerBaseTest {
        // THEN the lock icon is shown
        verify(mLockIconView).setImportantForAccessibility(View.IMPORTANT_FOR_ACCESSIBILITY_YES);
    }

    @Test
    public void playHaptic_onTouchExploration_NoOneWayHaptics_usesVibrate() {
        mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, false);

        // WHEN request to vibrate on touch exploration
        mUnderTest.vibrateOnTouchExploration();

        // THEN vibrates
        verify(mVibrator).vibrate(
                anyInt(),
                any(),
                eq(UdfpsController.EFFECT_CLICK),
                eq("lock-icon-down"),
                any());
    }

    @Test
    public void playHaptic_onTouchExploration_withOneWayHaptics_performHapticFeedback() {
        mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);

        // WHEN request to vibrate on touch exploration
        mUnderTest.vibrateOnTouchExploration();

        // THEN performHapticFeedback is used
        verify(mVibrator).performHapticFeedback(any(), eq(HapticFeedbackConstants.CONTEXT_CLICK));
    }

    @Test
    public void playHaptic_onLongPress_NoOneWayHaptics_usesVibrate() {
        mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, false);

        // WHEN request to vibrate on long press
        mUnderTest.vibrateOnLongPress();

        // THEN uses vibrate
        verify(mVibrator).vibrate(
                anyInt(),
                any(),
                eq(UdfpsController.EFFECT_CLICK),
                eq("lock-screen-lock-icon-longpress"),
                any());
    }

    @Test
    public void playHaptic_onLongPress_withOneWayHaptics_performHapticFeedback() {
        mFeatureFlags.set(ONE_WAY_HAPTICS_API_MIGRATION, true);

        // WHEN request to vibrate on long press
        mUnderTest.vibrateOnLongPress();

        // THEN uses perform haptic feedback
        verify(mVibrator).performHapticFeedback(any(), eq(UdfpsController.LONG_PRESS));

    }
}