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

Commit ae73f327 authored by Andy Mast's avatar Andy Mast
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
(cherry picked from commit f3c64cc7)
parent d330115f
Loading
Loading
Loading
Loading
+30 −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,10 @@ public class FingerprintManager {
                        break;
                    case MSG_REMOVED:
                        mClientReceiver.onRemoved(msg.arg1);
                        break;
                    case MSG_STATE_CHANGE:
                        mClientReceiver.onStateChanged(msg.arg1);
                        break;
                }
            }
        }
@@ -133,6 +144,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 +259,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
@@ -150,6 +150,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;
@@ -595,6 +596,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);
@@ -1566,9 +1577,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