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

Commit 80a776e5 authored by Jim Miller's avatar Jim Miller
Browse files

Remove redundant cancel events from FingerprintService

This fixes a bug where the framework was sending repeat cancel
events in response to terminal status (onAuthenticated(), onError())
which causes the underlying HAL implementation to get into a weird state.

Now, only client-initiated events like an explicit cancellation
or starting another authentication/enrollment invokes fingerprintd's
cancel() method.

Fixes bug 22438498

Change-Id: I762bab1c8635924848f9f4334db47a07130d5ae3
parent f6586cbd
Loading
Loading
Loading
Loading
+38 −23
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
    private static final int FINGERPRINT_ACQUIRED_GOOD = 0;

    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case MSG_USER_SWITCHING:
@@ -274,7 +275,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
            Slog.w(TAG, "enroll: no fingeprintd!");
            return;
        }
        stopPendingOperations();
        stopPendingOperations(true);
        mEnrollClient = new ClientMonitor(token, receiver, groupId, restricted);
        final int timeout = (int) (ENROLLMENT_TIMEOUT_MS / MS_PER_SEC);
        try {
@@ -315,17 +316,23 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
        return 0;
    }

    private void stopPendingOperations() {
    private void stopPendingOperations(boolean initiatedByClient) {
        if (mEnrollClient != null) {
            stopEnrollment(mEnrollClient.token, true);
            stopEnrollment(mEnrollClient.token, initiatedByClient);
        }
        if (mAuthClient != null) {
            stopAuthentication(mAuthClient.token, true);
            stopAuthentication(mAuthClient.token, initiatedByClient);
        }
        // mRemoveClient is allowed to continue
    }

    void stopEnrollment(IBinder token, boolean notify) {
    /**
     * Stop enrollment in progress and inform client if they initiated it.
     *
     * @param token token for client
     * @param initiatedByClient if this call is the result of client action (e.g. calling cancel)
     */
    void stopEnrollment(IBinder token, boolean initiatedByClient) {
        IFingerprintDaemon daemon = getFingerprintDaemon();
        if (daemon == null) {
            Slog.w(TAG, "stopEnrollment: no fingeprintd!");
@@ -333,6 +340,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
        }
        final ClientMonitor client = mEnrollClient;
        if (client == null || client.token != token) return;
        if (initiatedByClient) {
            try {
                int result = daemon.cancelEnrollment();
                if (result != 0) {
@@ -341,7 +349,6 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
            } catch (RemoteException e) {
                Slog.e(TAG, "stopEnrollment failed", e);
            }
        if (notify) {
            client.sendError(FingerprintManager.FINGERPRINT_ERROR_CANCELED);
        }
        removeClient(mEnrollClient);
@@ -354,7 +361,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
            Slog.w(TAG, "startAuthentication: no fingeprintd!");
            return;
        }
        stopPendingOperations();
        stopPendingOperations(true);
        mAuthClient = new ClientMonitor(token, receiver, groupId, restricted);
        if (inLockoutMode()) {
            Slog.v(TAG, "In lockout mode; disallowing authentication");
@@ -374,7 +381,13 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
        }
    }

    void stopAuthentication(IBinder token, boolean notify) {
    /**
     * Stop authentication in progress and inform client if they initiated it.
     *
     * @param token token for client
     * @param initiatedByClient if this call is the result of client action (e.g. calling cancel)
     */
    void stopAuthentication(IBinder token, boolean initiatedByClient) {
        IFingerprintDaemon daemon = getFingerprintDaemon();
        if (daemon == null) {
            Slog.w(TAG, "stopAuthentication: no fingeprintd!");
@@ -382,6 +395,7 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
        }
        final ClientMonitor client = mAuthClient;
        if (client == null || client.token != token) return;
        if (initiatedByClient) {
            try {
                int result = daemon.cancelAuthentication();
                if (result != 0) {
@@ -390,7 +404,6 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
            } catch (RemoteException e) {
                Slog.e(TAG, "stopAuthentication failed", e);
            }
        if (notify) {
            client.sendError(FingerprintManager.FINGERPRINT_ERROR_CANCELED);
        }
        removeClient(mAuthClient);
@@ -486,12 +499,14 @@ public class FingerprintService extends SystemService implements IBinder.DeathRe
            receiver = null;
        }

        @Override
        public void binderDied() {
            token = null;
            removeClient(this);
            receiver = null;
        }

        @Override
        protected void finalize() throws Throwable {
            try {
                if (token != null) {