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
This commit is contained in:
Juan Sebastian Martinez
2023-08-02 11:39:00 -07:00
parent 0ac981822d
commit afa5fd51a5
2 changed files with 95 additions and 13 deletions

View File

@@ -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) {

View File

@@ -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));
}
}