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

Commit f41fc966 authored by Jim Miller's avatar Jim Miller
Browse files

Add fingerprint detection support to Keyguard.

Tested:
- power-on with fingerprint sensor
- dismiss bouncer with fingerprint
- fingerprint to enter trusted state

Change-Id: I6aab7591d370412a143fe219a1575b2719a4de96
parent 155854f5
Loading
Loading
Loading
Loading
+84 −5
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
import android.app.trust.TrustManager;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -49,6 +50,9 @@ import android.provider.Settings;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.TelephonyIntents;

import android.service.fingerprint.FingerprintManager;
import android.service.fingerprint.FingerprintManagerReceiver;
import android.service.fingerprint.FingerprintUtils;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.SparseBooleanArray;
@@ -89,13 +93,17 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
    private static final int MSG_USER_SWITCHING = 310;
    private static final int MSG_USER_REMOVED = 311;
    private static final int MSG_KEYGUARD_VISIBILITY_CHANGED = 312;
    protected static final int MSG_BOOT_COMPLETED = 313;
    private static final int MSG_BOOT_COMPLETED = 313;
    private static final int MSG_USER_SWITCH_COMPLETE = 314;
    protected static final int MSG_USER_INFO_CHANGED = 317;
    protected static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
    private static final int MSG_SET_CURRENT_CLIENT_ID = 315;
    private static final int MSG_SET_PLAYBACK_STATE = 316;
    private static final int MSG_USER_INFO_CHANGED = 317;
    private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
    private static final int MSG_SCREEN_TURNED_ON = 319;
    private static final int MSG_SCREEN_TURNED_OFF = 320;
    private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
    private static final int MSG_FINGERPRINT_PROCESSED = 323;
    private static final int MSG_FINGERPRINT_ACQUIRED = 324;

    private static KeyguardUpdateMonitor sInstance;

@@ -194,11 +202,18 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
                case MSG_SCREEN_TURNED_ON:
                    handleScreenTurnedOn();
                    break;
                case MSG_FINGERPRINT_ACQUIRED:
                    handleFingerprintAcquired(msg.arg1);
                    break;
                case MSG_FINGERPRINT_PROCESSED:
                    handleFingerprintProcessed(msg.arg1);
                    break;
            }
        }
    };

    private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
    private SparseBooleanArray mUserFingerprintRecognized = new SparseBooleanArray();

    @Override
    public void onTrustChanged(boolean enabled, int userId) {
@@ -212,6 +227,44 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
        }
    }

    private void onFingerprintRecognized(int userId) {
        mUserFingerprintRecognized.put(userId, true);
        for (int i = 0; i < mCallbacks.size(); i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
            if (cb != null) {
                cb.onFingerprintRecognized(userId);
            }
        }
    }

    private void handleFingerprintProcessed(int fingerprintId) {
        if (fingerprintId == 0) return; // not a valid fingerprint

        final int userId;
        try {
            userId = ActivityManagerNative.getDefault().getCurrentUser().id;
        } catch (RemoteException e) {
            Log.e(TAG, "Failed to get current user id: ", e);
            return;
        }
        final ContentResolver res = mContext.getContentResolver();
        final int ids[] = FingerprintUtils.getFingerprintIdsForUser(res, userId);
        for (int i = 0; i < ids.length; i++) {
            if (ids[i] == fingerprintId) {
                onFingerprintRecognized(userId);
            }
        }
    }

    private void handleFingerprintAcquired(int info) {
        for (int i = 0; i < mCallbacks.size(); i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
            if (cb != null) {
                cb.onFingerprintAcquired(info);
            }
        }
    }

    private boolean isTrustDisabled(int userId) {
        final DevicePolicyManager dpm =
                (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
@@ -234,7 +287,8 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
    }

    public boolean getUserHasTrust(int userId) {
        return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
        return !isTrustDisabled(userId) && mUserHasTrust.get(userId)
                || mUserFingerprintRecognized.get(userId);
    }

    static class DisplayClientState {
@@ -304,6 +358,23 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
            }
        }
    };
    private FingerprintManagerReceiver mFingerprintManagerReceiver =
            new FingerprintManagerReceiver() {
        @Override
        public void onProcessed(int fingerprintId) {
            mHandler.obtainMessage(MSG_FINGERPRINT_PROCESSED, fingerprintId, 0).sendToTarget();
        };

        @Override
        public void onAcquired(int info) {
            mHandler.obtainMessage(MSG_FINGERPRINT_ACQUIRED, info, 0).sendToTarget();
        }

        @Override
        public void onError(int error) {
            if (DEBUG) Log.w(TAG, "FingerprintManager reported error: " + error);
        }
    };

    /**
     * When we receive a
@@ -425,6 +496,7 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
    }

    protected void handleScreenTurnedOff(int arg1) {
        clearFingerprintRecognized();
        final int count = mCallbacks.size();
        for (int i = 0; i < count; i++) {
            KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -459,7 +531,6 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {

    private KeyguardUpdateMonitor(Context context) {
        mContext = context;

        mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
        // Since device can't be un-provisioned, we only need to register a content observer
        // to update mDeviceProvisioned when we are...
@@ -518,6 +589,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {

        TrustManager trustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
        trustManager.registerTrustListener(this);

        FingerprintManager fpm;
        fpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
        fpm.startListening(mFingerprintManagerReceiver);
    }

    private boolean isDeviceProvisionedInSettingsDb() {
@@ -1007,6 +1082,10 @@ public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
        mFailedBiometricUnlockAttempts = 0;
    }

    public void clearFingerprintRecognized() {
        mUserFingerprintRecognized.clear();
    }

    public void reportFailedUnlockAttempt() {
        mFailedAttempts++;
    }
+12 −0
Original line number Diff line number Diff line
@@ -172,4 +172,16 @@ public class KeyguardUpdateMonitorCallback {
     * Called when trust changes for a user.
     */
    public void onTrustChanged(int userId) { }

    /**
     * Called when a fingerprint is recognized.
     * @param userId
     */
    public void onFingerprintRecognized(int userId) { }

    /**
     * Called when fingerprint is acquired but not yet recognized
     */
    public void onFingerprintAcquired(int info) { }

}
+7 −0
Original line number Diff line number Diff line
@@ -392,6 +392,12 @@ public class KeyguardViewMediator extends SystemUI {
            }
        }

        public void onFingerprintRecognized(int userId) {
            if (mStatusBarKeyguardViewManager.isBouncerShowing()) {
                mViewMediatorCallback.keyguardDone(true);
            }
        };

    };

    ViewMediatorCallback mViewMediatorCallback = new ViewMediatorCallback() {
@@ -1079,6 +1085,7 @@ public class KeyguardViewMediator extends SystemUI {
        if (authenticated) {
            mUpdateMonitor.clearFailedUnlockAttempts();
        }
        mUpdateMonitor.clearFingerprintRecognized();

        if (mExitSecureCallback != null) {
            try {
+4 −0
Original line number Diff line number Diff line
@@ -248,6 +248,10 @@ public class StatusBarKeyguardViewManager {
        return false;
    }

    public boolean isBouncerShowing() {
        return mBouncer.isShowing();
    }

    private void updateStates() {
        int vis = mContainer.getSystemUiVisibility();
        boolean showing = mShowing;
+4 −0
Original line number Diff line number Diff line
@@ -99,6 +99,10 @@ public class UnlockMethodCache {
        public void onScreenTurnedOn() {
            updateMethodSecure(false /* updateAlways */);
        }

        public void onFingerprintRecognized(int userId) {
            updateMethodSecure(false /* updateAlways */);
        }
    };

    public static interface OnUnlockMethodChangedListener {