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

Commit 6726fd5c authored by Michael Wright's avatar Michael Wright
Browse files

Update fingerprint haptic patterns

Have fingerprint take advantage of the haptics capabilities of new
devices. In particular, use prebaked DOUBLE_CLICK effect for failure
since we tune that to feel good for a specific piece of hardware, and
use the equivalent of the long press effect since we tune that to be the
strongest feeling single click effect that doesn't cause the device to
feel "buzzy" or annoying.

Bug: 62392467
Test: manual
Change-Id: I9331718b1d515959a4b5f8bd0f17243b28a6f788
parent 91d763f1
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -79,7 +79,7 @@ public abstract class AuthenticationClient extends ClientMonitor {
        }
        if (!authenticated) {
            if (receiver != null) {
                FingerprintUtils.vibrateFingerprintError(getContext());
                vibrateError();
            }
            // allow system-defined limit of number of attempts before giving up
            int lockoutMode =  handleFailedAttempt();
@@ -99,7 +99,7 @@ public abstract class AuthenticationClient extends ClientMonitor {
            result |= lockoutMode != LOCKOUT_NONE; // in a lockout mode
        } else {
            if (receiver != null) {
                FingerprintUtils.vibrateFingerprintSuccess(getContext());
                vibrateSuccess();
            }
            result |= true; // we have a valid fingerprint, done
            resetFailedAttempts();
+50 −7
Original line number Diff line number Diff line
@@ -23,6 +23,8 @@ import android.hardware.fingerprint.FingerprintManager;
import android.hardware.fingerprint.IFingerprintServiceReceiver;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.VibrationEffect;
import android.os.Vibrator;
import android.util.Slog;

import java.util.NoSuchElementException;
@@ -36,14 +38,18 @@ public abstract class ClientMonitor implements IBinder.DeathRecipient {
    protected static final String TAG = FingerprintService.TAG; // TODO: get specific name
    protected static final int ERROR_ESRCH = 3; // Likely fingerprint HAL is dead. See errno.h.
    protected static final boolean DEBUG = FingerprintService.DEBUG;
    private static final long[] DEFAULT_SUCCESS_VIBRATION_PATTERN = new long[] {0, 30};
    private final Context mContext;
    private final long mHalDeviceId;
    private final int mTargetUserId;
    private final int mGroupId;
    // True if client does not have MANAGE_FINGERPRINT permission
    private final boolean mIsRestricted;
    private final String mOwner;
    private final VibrationEffect mSuccessVibrationEffect;
    private final VibrationEffect mErrorVibrationEffect;
    private IBinder mToken;
    private IFingerprintServiceReceiver mReceiver;
    private int mTargetUserId;
    private int mGroupId;
    private boolean mIsRestricted; // True if client does not have MANAGE_FINGERPRINT permission
    private String mOwner;
    private Context mContext;
    private long mHalDeviceId;
    protected boolean mAlreadyCancelled;

    /**
@@ -68,6 +74,8 @@ public abstract class ClientMonitor implements IBinder.DeathRecipient {
        mGroupId = groupId;
        mIsRestricted = restricted;
        mOwner = owner;
        mSuccessVibrationEffect = getSuccessVibrationEffect(context);
        mErrorVibrationEffect = VibrationEffect.get(VibrationEffect.EFFECT_DOUBLE_CLICK);
        try {
            if (token != null) {
                token.linkToDeath(this, 0);
@@ -79,7 +87,7 @@ public abstract class ClientMonitor implements IBinder.DeathRecipient {

    /**
     * Contacts fingerprint HAL to start the client.
     * @return 0 on succes, errno from driver on failure
     * @return 0 on success, errno from driver on failure
     */
    public abstract int start();

@@ -211,4 +219,39 @@ public abstract class ClientMonitor implements IBinder.DeathRecipient {
    public final IBinder getToken() {
        return mToken;
    }

    public final void vibrateSuccess() {
        Vibrator vibrator = mContext.getSystemService(Vibrator.class);
        if (vibrator != null) {
            vibrator.vibrate(mSuccessVibrationEffect);
        }
    }

    public final void vibrateError() {
        Vibrator vibrator = mContext.getSystemService(Vibrator.class);
        if (vibrator != null) {
            vibrator.vibrate(mErrorVibrationEffect);
        }
    }

    private static VibrationEffect getSuccessVibrationEffect(Context ctx) {
        int[] arr = ctx.getResources().getIntArray(
                com.android.internal.R.array.config_longPressVibePattern);
        final long[] vibePattern;
        if (arr == null || arr.length == 0) {
            vibePattern = DEFAULT_SUCCESS_VIBRATION_PATTERN;
        } else {
            vibePattern = new long[arr.length];
            for (int i = 0; i < arr.length; i++) {
                vibePattern[i] = arr[i];
            }
        }
        if (vibePattern.length == 1) {
            return VibrationEffect.createOneShot(
                    vibePattern[0], VibrationEffect.DEFAULT_AMPLITUDE);
        } else {
            return VibrationEffect.createWaveform(vibePattern, -1);
        }
    }

}
+1 −1
Original line number Diff line number Diff line
@@ -65,7 +65,7 @@ public abstract class EnrollClient extends ClientMonitor {
        if (receiver == null)
            return true; // client not listening

        FingerprintUtils.vibrateFingerprintSuccess(getContext());
        vibrateSuccess();
        MetricsLogger.action(getContext(), MetricsEvent.ACTION_FINGERPRINT_ENROLL);
        try {
            receiver.onEnrollResult(getHalDeviceId(), fpId, groupId, remaining);
+0 −18
Original line number Diff line number Diff line
@@ -18,7 +18,6 @@ package com.android.server.fingerprint;

import android.content.Context;
import android.hardware.fingerprint.Fingerprint;
import android.os.Vibrator;
import android.text.TextUtils;
import android.util.SparseArray;

@@ -31,9 +30,6 @@ import java.util.List;
 */
public class FingerprintUtils {

    private static final long[] FP_ERROR_VIBRATE_PATTERN = new long[] {0, 30, 100, 30};
    private static final long[] FP_SUCCESS_VIBRATE_PATTERN = new long[] {0, 30};

    private static final Object sInstanceLock = new Object();
    private static FingerprintUtils sInstance;

@@ -72,20 +68,6 @@ public class FingerprintUtils {
        getStateForUser(ctx, userId).renameFingerprint(fingerId, name);
    }

    public static void vibrateFingerprintError(Context context) {
        Vibrator vibrator = context.getSystemService(Vibrator.class);
        if (vibrator != null) {
            vibrator.vibrate(FP_ERROR_VIBRATE_PATTERN, -1);
        }
    }

    public static void vibrateFingerprintSuccess(Context context) {
        Vibrator vibrator = context.getSystemService(Vibrator.class);
        if (vibrator != null) {
            vibrator.vibrate(FP_SUCCESS_VIBRATE_PATTERN, -1);
        }
    }

    private FingerprintsUserState getStateForUser(Context ctx, int userId) {
        synchronized (this) {
            FingerprintsUserState state = mUsers.get(userId);