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

Commit f3c64cc7 authored by Andy Mast's avatar Andy Mast Committed by Gerrit Code Review
Browse files

Authenticate When Keyguard Resumes From Camera

Before this patch, fingerprint would stop working if a user went
to the camera inside keyguard. This is because keyguard would
not re-authenticate when it resumed from camera.

This patch introduces lazy authentication because Camera's onPause
can happen before or concurrently to Keyguard's occlusion callback.
This means Keyguard can get in a situation where it tries to
authenticate when FingerprintService is already authenticating.

Issue-Id: SAMBAR-205

Change-Id: I57bdad5140d172c0ffb963010e12cb72e85663e7
parent c8ff1a91
Loading
Loading
Loading
Loading
+28 −0
Original line number Diff line number Diff line
@@ -46,6 +46,7 @@ public class FingerprintManager {
    private static final int MSG_PROCESSED = 102;
    private static final int MSG_ERROR = 103;
    private static final int MSG_REMOVED = 104;
    private static final int MSG_STATE_CHANGE = 105;

    // Errors generated by layers above HAL
    public static final int FINGERPRINT_ERROR_NO_RECEIVER = -10;
@@ -73,6 +74,12 @@ public class FingerprintManager {
    public static final int FINGERPRINT_ACQUIRED_TOO_SLOW = 8;
    public static final int FINGERPRINT_ACQUIRED_TOO_FAST = 16;

    // Fingerprint States
    public static final int STATE_UNKNOWN = -1;
    public static final int STATE_IDLE = 0;
    public static final int STATE_AUTHENTICATING = 1;
    public static final int STATE_ENROLLING = 2;

    private IFingerprintService mService;
    private FingerprintManagerReceiver mClientReceiver;
    private Context mContext;
@@ -96,6 +103,8 @@ public class FingerprintManager {
                        break;
                    case MSG_REMOVED:
                        mClientReceiver.onRemoved(msg.arg1);
                    case MSG_STATE_CHANGE:
                        mClientReceiver.onStateChanged(msg.arg1);
                }
            }
        }
@@ -133,6 +142,11 @@ public class FingerprintManager {
        public void onRemoved(int fingerprintId) {
            mHandler.obtainMessage(MSG_REMOVED, fingerprintId, 0).sendToTarget();
        }

        public void onStateChanged(int state) {
            mHandler.obtainMessage(MSG_STATE_CHANGE, state, 0).sendToTarget();
        }

    };

    /**
@@ -243,6 +257,20 @@ public class FingerprintManager {
        }
    }

    public int getState() {
        if (mService != null) {
            try {
                return mService.getState();
            } catch (RemoteException e) {
                Log.v(TAG, "Remote exception in getState(): ", e);
            }
        } else {
            Log.w(TAG, "getState(): Service not connected!");
            sendError(FINGERPRINT_ERROR_HW_UNAVAILABLE, 0, 0);
        }
        return STATE_UNKNOWN;
    }

    private int getCurrentUserId() {
        return Process.myUserHandle().getIdentifier();
    }
+6 −0
Original line number Diff line number Diff line
@@ -73,4 +73,10 @@ public class FingerprintManagerReceiver {
     * @param fingerprintId id of template to remove.
     */
    public void onRemoved(int fingerprintId) { }

    /**
     * When the fingerprint service's state changes
     * @param state
     */
    public void onStateChanged(int state) { }
}
 No newline at end of file
+3 −0
Original line number Diff line number Diff line
@@ -50,4 +50,7 @@ interface IFingerprintService {

    // Get num of fingerprints samples required to enroll
    int getNumEnrollmentSteps(IBinder token);

    // Return the state of FingerprintService
    int getState();
}
+1 −0
Original line number Diff line number Diff line
@@ -28,4 +28,5 @@ oneway interface IFingerprintServiceReceiver {
    void onProcessed(int fingerprintId);
    void onError(int error);
    void onRemoved(int fingerprintId);
    void onStateChanged(int state);
}
+21 −1
Original line number Diff line number Diff line
@@ -139,6 +139,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
    private boolean mKeyguardIsVisible;
    private boolean mBouncer;
    private boolean mBootCompleted;
    private boolean mStartFingerAuthOnIdle;

    // Device provisioning state
    private boolean mDeviceProvisioned;
@@ -551,6 +552,16 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
            mHandler.obtainMessage(MSG_FINGERPRINT_ACQUIRED, info, 0).sendToTarget();
        }

        @Override
        public void onStateChanged(int state) {
            if (state == FingerprintManager.STATE_IDLE && mStartFingerAuthOnIdle) {
                mStartFingerAuthOnIdle = false;
                FingerprintManager fpm =
                        (FingerprintManager) mContext.getSystemService(Context.FINGERPRINT_SERVICE);
                fpm.authenticate();
            }
        }

        @Override
        public void onError(int error) {
            if (DEBUG) Log.w(TAG, "FingerprintManager reported error: " + error);
@@ -1289,9 +1300,18 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
            FingerprintManager fpm =
                    (FingerprintManager) mContext.getSystemService(Context.FINGERPRINT_SERVICE);
            fpm.startListening(mFingerprintManagerReceiver);

            // Lazily authenticate if the state isn't ready yet. This can happen
            // if another app (like camera) is stopping and keyguard is resuming, but
            // camera hasn't received its onPause method yet to cleanup its fingerprint connection
            if (FingerprintManager.STATE_IDLE != fpm.getState()) {
                mStartFingerAuthOnIdle = true;
            } else {
                // Fingerprint service is already idle, ready to authenticate
                fpm.authenticate();
            }
        }
    }

    public void stopAuthenticatingFingerprint() {
        if (mLockPatternUtils.isFingerprintInstalled(mContext)) {
Loading