Enable start haptic for udfps by default
When the user's touch first enters the udfps area, play the keyboard pressed (click) haptic feedback. Test: manual, atest UdfpsControllerTest Fixes: 187535630 Bug: 185124905 Change-Id: I2e5231e74dbbc2617ba9f0f04127827fd14078e9
This commit is contained in:
@@ -105,7 +105,7 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
@NonNull private final DumpManager mDumpManager;
|
||||
@NonNull private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
|
||||
@NonNull private final KeyguardViewMediator mKeyguardViewMediator;
|
||||
@NonNull private final Vibrator mVibrator;
|
||||
@Nullable private final Vibrator mVibrator;
|
||||
@NonNull private final Handler mMainHandler;
|
||||
@NonNull private final FalsingManager mFalsingManager;
|
||||
@NonNull private final PowerManager mPowerManager;
|
||||
@@ -135,7 +135,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
private boolean mScreenOn;
|
||||
private Runnable mAodInterruptRunnable;
|
||||
|
||||
private static final AudioAttributes VIBRATION_SONIFICATION_ATTRIBUTES =
|
||||
@VisibleForTesting
|
||||
static final AudioAttributes VIBRATION_SONIFICATION_ATTRIBUTES =
|
||||
new AudioAttributes.Builder()
|
||||
.setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
|
||||
.setUsage(AudioAttributes.USAGE_ASSISTANCE_SONIFICATION)
|
||||
@@ -144,7 +145,8 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
private final VibrationEffect mEffectTick = VibrationEffect.get(VibrationEffect.EFFECT_TICK);
|
||||
private final VibrationEffect mEffectTextureTick =
|
||||
VibrationEffect.get(VibrationEffect.EFFECT_TEXTURE_TICK);
|
||||
private final VibrationEffect mEffectClick = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
|
||||
@VisibleForTesting
|
||||
final VibrationEffect mEffectClick = VibrationEffect.get(VibrationEffect.EFFECT_CLICK);
|
||||
private final VibrationEffect mEffectHeavy =
|
||||
VibrationEffect.get(VibrationEffect.EFFECT_HEAVY_CLICK);
|
||||
private final VibrationEffect mDoubleClick =
|
||||
@@ -152,6 +154,9 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
private final Runnable mAcquiredVibration = new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (mVibrator == null) {
|
||||
return;
|
||||
}
|
||||
String effect = Settings.Global.getString(mContext.getContentResolver(),
|
||||
"udfps_acquired_type");
|
||||
mVibrator.vibrate(getVibration(effect, mEffectTick), VIBRATION_SONIFICATION_ATTRIBUTES);
|
||||
@@ -389,24 +394,28 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
PowerManager.USER_ACTIVITY_EVENT_TOUCH, 0);
|
||||
|
||||
// TODO: this should eventually be removed after ux testing
|
||||
final ContentResolver contentResolver = mContext.getContentResolver();
|
||||
int startEnabled = Settings.Global.getInt(contentResolver,
|
||||
"udfps_start", 0);
|
||||
if (startEnabled > 0) {
|
||||
String startEffectSetting = Settings.Global.getString(
|
||||
contentResolver, "udfps_start_type");
|
||||
mVibrator.vibrate(getVibration(startEffectSetting, mEffectClick),
|
||||
VIBRATION_SONIFICATION_ATTRIBUTES);
|
||||
if (mVibrator != null) {
|
||||
final ContentResolver contentResolver =
|
||||
mContext.getContentResolver();
|
||||
int startEnabled = Settings.Global.getInt(contentResolver,
|
||||
"udfps_start", 1);
|
||||
if (startEnabled > 0) {
|
||||
String startEffectSetting = Settings.Global.getString(
|
||||
contentResolver, "udfps_start_type");
|
||||
mVibrator.vibrate(getVibration(startEffectSetting,
|
||||
mEffectClick), VIBRATION_SONIFICATION_ATTRIBUTES);
|
||||
}
|
||||
|
||||
int acquiredEnabled = Settings.Global.getInt(contentResolver,
|
||||
"udfps_acquired", 0);
|
||||
if (acquiredEnabled > 0) {
|
||||
int delay = Settings.Global.getInt(contentResolver,
|
||||
"udfps_acquired_delay", 500);
|
||||
mMainHandler.removeCallbacks(mAcquiredVibration);
|
||||
mMainHandler.postDelayed(mAcquiredVibration, delay);
|
||||
}
|
||||
}
|
||||
|
||||
int acquiredEnabled = Settings.Global.getInt(contentResolver,
|
||||
"udfps_acquired", 0);
|
||||
if (acquiredEnabled > 0) {
|
||||
int delay = Settings.Global.getInt(contentResolver,
|
||||
"udfps_acquired_delay", 500);
|
||||
mMainHandler.removeCallbacks(mAcquiredVibration);
|
||||
mMainHandler.postDelayed(mAcquiredVibration, delay);
|
||||
}
|
||||
handled = true;
|
||||
} else if (sinceLastLog >= MIN_TOUCH_LOG_INTERVAL) {
|
||||
Log.v(TAG, "onTouch | finger move: " + touchInfo);
|
||||
@@ -456,11 +465,12 @@ public class UdfpsController implements DozeReceiver, HbmCallback {
|
||||
@NonNull FalsingManager falsingManager,
|
||||
@NonNull PowerManager powerManager,
|
||||
@NonNull AccessibilityManager accessibilityManager,
|
||||
@NonNull ScreenLifecycle screenLifecycle) {
|
||||
@NonNull ScreenLifecycle screenLifecycle,
|
||||
@Nullable Vibrator vibrator) {
|
||||
mContext = context;
|
||||
// TODO (b/185124905): inject main handler and vibrator once done prototyping
|
||||
mMainHandler = new Handler(Looper.getMainLooper());
|
||||
mVibrator = context.getSystemService(Vibrator.class);
|
||||
mVibrator = vibrator;
|
||||
mInflater = inflater;
|
||||
// The fingerprint manager is queried for UDFPS before this class is constructed, so the
|
||||
// fingerprint manager should never be null.
|
||||
|
||||
@@ -35,6 +35,7 @@ import android.hardware.fingerprint.IUdfpsOverlayController;
|
||||
import android.hardware.fingerprint.IUdfpsOverlayControllerCallback;
|
||||
import android.os.PowerManager;
|
||||
import android.os.RemoteException;
|
||||
import android.os.Vibrator;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
import android.testing.TestableLooper.RunWithLooper;
|
||||
import android.view.LayoutInflater;
|
||||
@@ -114,6 +115,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
private AccessibilityManager mAccessibilityManager;
|
||||
@Mock
|
||||
private ScreenLifecycle mScreenLifecycle;
|
||||
@Mock
|
||||
private Vibrator mVibrator;
|
||||
|
||||
private FakeExecutor mFgExecutor;
|
||||
|
||||
@@ -170,7 +173,8 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
mFalsingManager,
|
||||
mPowerManager,
|
||||
mAccessibilityManager,
|
||||
mScreenLifecycle);
|
||||
mScreenLifecycle,
|
||||
mVibrator);
|
||||
verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
|
||||
mOverlayController = mOverlayCaptor.getValue();
|
||||
verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
|
||||
@@ -302,4 +306,29 @@ public class UdfpsControllerTest extends SysuiTestCase {
|
||||
// THEN no illumination because screen is off
|
||||
verify(mUdfpsView, never()).startIllumination(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void playHapticOnTouchUdfpsArea() throws RemoteException {
|
||||
// Configure UdfpsView to accept the ACTION_DOWN event
|
||||
when(mUdfpsView.isIlluminationRequested()).thenReturn(false);
|
||||
when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
|
||||
|
||||
// GIVEN that the overlay is showing
|
||||
mOverlayController.showUdfpsOverlay(TEST_UDFPS_SENSOR_ID,
|
||||
IUdfpsOverlayController.REASON_AUTH_FPM_KEYGUARD, mUdfpsOverlayControllerCallback);
|
||||
mFgExecutor.runAllReady();
|
||||
|
||||
// WHEN ACTION_DOWN is received
|
||||
verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
|
||||
MotionEvent downEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_DOWN, 0, 0, 0);
|
||||
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
|
||||
downEvent.recycle();
|
||||
MotionEvent moveEvent = MotionEvent.obtain(0, 0, MotionEvent.ACTION_MOVE, 0, 0, 0);
|
||||
mTouchListenerCaptor.getValue().onTouch(mUdfpsView, moveEvent);
|
||||
moveEvent.recycle();
|
||||
|
||||
// THEN click haptic is played
|
||||
verify(mVibrator).vibrate(mUdfpsController.mEffectClick,
|
||||
UdfpsController.VIBRATION_SONIFICATION_ATTRIBUTES);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user