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

Commit 85d9e16c authored by Jim Miller's avatar Jim Miller Committed by Android (Google) Code Review
Browse files

Merge "Update Settings to use new fingerprint API"

parents c735941a d16c9b7c
Loading
Loading
Loading
Loading
+2 −17
Original line number Diff line number Diff line
@@ -764,7 +764,8 @@
    </plurals>
    <!-- Introduction title shown in fingerprint enrollment dialog [CHAR LIMIT=22] -->
    <string name="security_settings_fingerprint_enroll_onboard_title">Fingerprint setup</string>
    <!-- Introduction detail message shown in fingerprint enrollment dialog -->
    <!-- Introduction message shown in fingerprint enrollment dialog when the user needs to choose an 
         alternate screen unlock (pin, pattern or password) as a backup to fingerprint. -->
    <string name="security_settings_fingerprint_enroll_onboard_message">
        To use your fingerprint to unlock your screen or confirm purchases, we\'ll need to:
        \n\n\u2713 Set up your backup screen lock method
@@ -796,22 +797,6 @@
    <string name="fingerprint_enroll_button_add">Add</string>
    <!-- Button text shown at the end of enrollment that allows the user to move to the next step -->
    <string name="fingerprint_enroll_button_next">Next</string>
    <!-- Error message shown when the fingerprint cannot be recognized -->
    <string name="fingerprint_acquired_try_again">Partial fingerprint detected. Please try again.</string>
    <!-- Error message shown when the fingerprint sensor needs cleaning -->
    <string name="fingerprint_acquired_imager_dirty">Fingerprint sensor is dirty. Please clean and try again.</string>
    <!-- Error message shown when the user removes their finger from the sensor too quickly -->
    <string name="fingerprint_acquired_too_fast">Finger moved to fast. Please try again.</string>
    <!-- Error message shown when the user moves their finger too slowly -->
    <string name="fingerprint_acquired_too_slow">Finger moved to slow. Please try again.</string>
    <!-- Generic error message shown when the fingerprint hardware can't recognize the fingerprint -->
    <string name="fingerprint_error_unable_to_process">Unable to process. Try again.</string>
    <!-- Error message shown when the fingerprint hardware can't be accessed -->
    <string name="fingerprint_error_hw_not_available">Hardware not available.</string>
    <!-- Error message shown when the fingerprint hardware has run out of room for storing fingerprints -->
    <string name="fingerprint_error_no_space">Fingerprint can\'t be stored. Please remove an existing fingerprint.</string>
    <!-- Error message shown when the fingerprint hardware timer has expired and the user needs to restart the operation. -->
    <string name="fingerprint_error_timeout">Fingerprint time out reached. Try again.</string>

    <!-- Title of the preferences category for preference items to control encryption -->
    <string name="crypt_keeper_settings_title">Encryption</string>
+17 −12
Original line number Diff line number Diff line
@@ -34,11 +34,14 @@ import android.os.UserManager;
import android.preference.Preference;
import android.preference.PreferenceScreen;
import android.security.KeyStore;
import android.service.fingerprint.Fingerprint;
import android.service.fingerprint.FingerprintManager;
import android.service.fingerprint.FingerprintManagerReceiver;
import android.service.fingerprint.FingerprintManager.RemovalCallback;
import android.util.EventLog;
import android.util.Log;
import android.view.accessibility.AccessibilityManager;
import android.widget.Toast;

import com.android.internal.widget.LockPatternUtils;

import java.util.List;
@@ -96,6 +99,18 @@ public class ChooseLockGeneric extends SettingsActivity {
        private boolean mRequirePassword;
        private LockPatternUtils mLockPatternUtils;
        private FingerprintManager mFingerprintManager;
        private RemovalCallback mRemovalCallback = new RemovalCallback() {

            @Override
            public void onRemovalSucceeded(Fingerprint fingerprint) {
                Log.v(TAG, "Fingerprint removed: " + fingerprint.getFingerId());
            }

            @Override
            public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString) {
                Toast.makeText(getActivity(), errString, Toast.LENGTH_SHORT);
            }
        };

        @Override
        public void onCreate(Bundle savedInstanceState) {
@@ -400,25 +415,15 @@ public class ChooseLockGeneric extends SettingsActivity {
            }
        }

        // TODO: This is only required because we used to enforce clients have a listener,
        // which is no longer required in the new API.  Remove when that happens.
        FingerprintManagerReceiver mReceiver = new FingerprintManagerReceiver() {
            public void onRemoved(int fingerprintId) {
                Log.v(TAG, "onRemoved(id=" + fingerprintId + ")");
            }
        };

        private void removeAllFingerprintTemplates() {
            if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) {
                mFingerprintManager.startListening(mReceiver);
                mFingerprintManager.remove(0 /* all fingerprint templates */);
                mFingerprintManager.remove(new Fingerprint(null, 0, 0, 0), mRemovalCallback);
            }
        }

        @Override
        public void onDestroy() {
            super.onDestroy();
            mFingerprintManager.stopListening();
        }

        @Override
+48 −68
Original line number Diff line number Diff line
@@ -24,16 +24,16 @@ import android.app.Fragment;
import android.app.admin.DevicePolicyManager;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.media.AudioAttributes;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.os.PowerManager;
import android.os.SystemClock;
import android.os.Vibrator;
import android.service.fingerprint.FingerprintManager;
import android.service.fingerprint.FingerprintManagerReceiver;
import android.service.fingerprint.FingerprintManager.EnrollmentCallback;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
@@ -82,12 +82,13 @@ public class FingerprintEnroll extends SettingsActivity {
    }

    public static class FingerprintEnrollFragment extends Fragment implements View.OnClickListener {
        private static final String EXTRA_PROGRESS = "progress";
        private static final String EXTRA_STAGE = "stage";
        private static final int PROGRESS_BAR_MAX = 10000;
        private static final String TAG = "FingerprintEnroll";
        private static final boolean DEBUG = true;
        private static final int CONFIRM_REQUEST = 101;
        private static final int CHOOSE_LOCK_GENERIC_REQUEST = 102;
        private static final long ENROLL_TIMEOUT = 300*1000;
        private static final int FINISH_DELAY = 250;

        private PowerManager mPowerManager;
@@ -128,6 +129,7 @@ public class FingerprintEnroll extends SettingsActivity {
            @Override
            public void onAnimationCancel(Animator animation) { }
        };
        private CancellationSignal mEnrollmentCancel = new CancellationSignal();

        // This contains a list of all views managed by the UI. Used to determine which views
        // need to be shown/hidden at each stage. It should be the union of the lists that follow
@@ -240,13 +242,12 @@ public class FingerprintEnroll extends SettingsActivity {
                case EnrollingFindSensor:
                    mEnrollmentSteps = -1;
                    mEnrolling = false;
                    mFingerprintManager.stopListening();
                    break;

                case EnrollingStart:
                    mEnrollmentSteps = -1;
                    mFingerprintManager.startListening(mReceiver);
                    mFingerprintManager.enroll(ENROLL_TIMEOUT);
                    long challenge = 0x12345; // TODO: get from keyguard confirmation
                    mFingerprintManager.enroll(challenge, mEnrollmentCallback, mEnrollmentCancel,0);
                    mProgressBar.setProgress(0);
                    mEnrolling = true;
                    startFingerprintAnimator(); // XXX hack - this should follow fingerprint detection
@@ -257,12 +258,10 @@ public class FingerprintEnroll extends SettingsActivity {

                case EnrollingFinish:
                    stopFingerprintAnimator(); // XXX hack - this should follow fingerprint detection
                    mFingerprintManager.stopListening();
                    mEnrolling = false;
                    break;

                default:
                    mFingerprintManager.stopListening();
                    break;
            }
        }
@@ -270,7 +269,7 @@ public class FingerprintEnroll extends SettingsActivity {
        private void cancelEnrollment() {
            if (mEnrolling) {
                if (DEBUG) Log.v(TAG, "Cancel enrollment\n");
                mFingerprintManager.enrollCancel();
                mEnrollmentCancel.cancel();
                mEnrolling = false;
            }
        }
@@ -278,9 +277,7 @@ public class FingerprintEnroll extends SettingsActivity {
        @Override
        public void onDetach() {
            super.onDetach();
            // Do a little cleanup
            cancelEnrollment();
            mFingerprintManager.stopListening();
            cancelEnrollment(); // Do a little cleanup
        }

        private void updateProgress(int progress) {
@@ -300,6 +297,10 @@ public class FingerprintEnroll extends SettingsActivity {
            mProgressAnim = anim;
        }

        protected void setMessage(CharSequence msg) {
            if (msg != null) mMessageText.setText(msg);
        }

        private void setMessage(int id) {
            if (id != 0) mMessageText.setText(id);
        }
@@ -308,9 +309,11 @@ public class FingerprintEnroll extends SettingsActivity {
            if (title != 0) mTitleText.setText(title);
        }

        private FingerprintManagerReceiver mReceiver = new FingerprintManagerReceiver() {
            public void onEnrollResult(int fingerprintId, int remaining) {
                if (DEBUG) Log.v(TAG, "onEnrollResult(id=" + fingerprintId + ", rem=" + remaining);
        private EnrollmentCallback mEnrollmentCallback = new EnrollmentCallback() {

            @Override
            public void onEnrollmentProgress(int remaining) {
                if (DEBUG) Log.v(TAG, "onEnrollResult(id=" + ", rem=" + remaining);
                if (mEnrollmentSteps == -1) {
                    mEnrollmentSteps = remaining;
                    updateStage(Stage.EnrollingRepeat);
@@ -325,62 +328,14 @@ public class FingerprintEnroll extends SettingsActivity {
                }
            }

            public void onError(int error) {
                switch(error) {
                    case FingerprintManager.FINGERPRINT_ERROR_UNABLE_TO_PROCESS:
                        setMessage(R.string.fingerprint_error_unable_to_process);
                        break;
                    case FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE:
                        setMessage(R.string.fingerprint_error_hw_not_available);
                        break;
                    case FingerprintManager.FINGERPRINT_ERROR_NO_SPACE:
                        setMessage(R.string.fingerprint_error_no_space);
                        break;
                    case FingerprintManager.FINGERPRINT_ERROR_TIMEOUT:
                        setMessage(R.string.fingerprint_error_timeout);
                        break;
                    case FingerprintManager.FINGERPRINT_ERROR_NO_RECEIVER:
                        Log.w(TAG, "Receiver not registered");
                        break;
                }
            }

            public void onRemoved(int fingerprintId) {
                if (DEBUG) Log.v(TAG, "onRemoved(id=" + fingerprintId + ")");
            }

            @Override
            public void onProcessed(int fingerprintId) {
                if (DEBUG) Log.v(TAG, "onProcessed(id=" + fingerprintId + ")");
            public void onEnrollmentHelp(int helpMsgId, CharSequence helpString) {
                setMessage(helpString);
            }

            public void onAcquired(int scanInfo) {
                int msgId = 0;
                startFingerprintAnimator();
                switch(scanInfo) {
                    case FingerprintManager.FINGERPRINT_ACQUIRED_GOOD:
                        break;
                    case FingerprintManager.FINGERPRINT_ACQUIRED_IMAGER_DIRTY:
                        msgId = R.string.fingerprint_acquired_imager_dirty;
                        break;
                    case FingerprintManager.FINGERPRINT_ACQUIRED_TOO_SLOW:
                        msgId = R.string.fingerprint_acquired_too_fast;
                        break;
                    case FingerprintManager.FINGERPRINT_ACQUIRED_TOO_FAST:
                        msgId = R.string.fingerprint_acquired_too_slow;
                        break;
                    case FingerprintManager.FINGERPRINT_ACQUIRED_PARTIAL:
                    case FingerprintManager.FINGERPRINT_ACQUIRED_INSUFFICIENT:
                        msgId = R.string.fingerprint_acquired_try_again;
                        break;
                    default:
                        // Try not to be too verbose in the UI. The user just needs to try again.
                        // Log the message so we can dig into the issue if necessary.
                        Log.w(TAG, "Try again because scanInfo was " + scanInfo);
                        msgId = R.string.fingerprint_acquired_try_again;
                        break;
                }
                setMessage(msgId);
            @Override
            public void onEnrollmentError(int errMsgId, CharSequence errString) {
                setMessage(errString);
            }
        };

@@ -431,6 +386,31 @@ public class FingerprintEnroll extends SettingsActivity {
            return mContentView;
        }

        @Override
        public void onSaveInstanceState(final Bundle outState) {
            super.onSaveInstanceState(outState);
            outState.putString(EXTRA_STAGE, mStage.toString());
            if (mStage == Stage.EnrollingRepeat) {
                outState.putInt(EXTRA_PROGRESS, mProgressBar.getProgress());
            }
        }

        @Override
        public void onActivityCreated(Bundle savedInstanceState) {
            super.onActivityCreated(savedInstanceState);
            if (savedInstanceState != null) {
                //probably orientation change
                String stageSaved = savedInstanceState.getString(EXTRA_STAGE, null);
                if (stageSaved != null) {
                    Stage stage = Stage.valueOf(stageSaved);
                    updateStage(stage);
                    if (stage == Stage.EnrollingRepeat) {
                        mProgressBar.setProgress(savedInstanceState.getInt(EXTRA_PROGRESS));
                    }
                }
            }
        }

        @Override
        public void onClick(View v) {
            switch(v.getId()) {
+71 −36
Original line number Diff line number Diff line
@@ -29,13 +29,16 @@ import android.preference.Preference;
import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.PreferenceGroup;
import android.preference.PreferenceScreen;
import android.service.fingerprint.Fingerprint;
import android.service.fingerprint.FingerprintManager;
import android.service.fingerprint.FingerprintManagerReceiver;
import android.service.fingerprint.FingerprintManager.FingerprintItem;
import android.service.fingerprint.FingerprintManager.AuthenticationCallback;
import android.service.fingerprint.FingerprintManager.RemovalCallback;
import android.service.fingerprint.FingerprintManager.AuthenticationResult;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.Toast;

import com.android.settings.search.Indexable;

@@ -68,6 +71,7 @@ public class FingerprintSettings extends SettingsActivity {

    public static class FingerprintSettingsFragment extends SettingsPreferenceFragment
        implements OnPreferenceChangeListener, Indexable {
        private static final int MAX_RETRY_ATTEMPTS = 5;
        private static final String TAG = "FingerprintSettings";
        private static final String KEY_FINGERPRINT_ITEM_PREFIX = "key_fingerprint_item";
        private static final String KEY_USAGE_CATEGORY = "fingerprint_usage_category";
@@ -82,10 +86,54 @@ public class FingerprintSettings extends SettingsActivity {
        private static final int ADD_FINGERPRINT_REQUEST = 10;

        private static final boolean ENABLE_USAGE_CATEGORY = false;
        protected static final boolean DEBUG = true;

        private FingerprintManager mFingerprintManager;
        private EditText mDialogTextField;
        private PreferenceGroup mManageCategory;
        private AuthenticationCallback mAuthCallback = new AuthenticationCallback() {
            int mAttempts;
            @Override
            public void onAuthenticationSucceeded(AuthenticationResult result) {
                mHandler.obtainMessage(MSG_HIGHLIGHT_FINGERPRINT_ITEM,
                        result.getFingerprint().getFingerId(), 0).sendToTarget();
                retryFingerprint(true);
            }

            @Override
            public void onAuthenticationError(int errMsgId, CharSequence errString) {
                Toast.makeText(getActivity(), errString, Toast.LENGTH_SHORT);
                retryFingerprint(false);
            }

            private void retryFingerprint(boolean resetAttempts) {
                if (resetAttempts) {
                    mAttempts = 0;
                }
                if (mAttempts < MAX_RETRY_ATTEMPTS) {
                    mFingerprintManager.authenticate(null, mAuthCallback, null, 0);
                }
                mAttempts++;
            }

            @Override
            public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
                Toast.makeText(getActivity(), helpString, Toast.LENGTH_SHORT);
            }
        };
        private RemovalCallback mRemoveCallback = new RemovalCallback() {

            @Override
            public void onRemovalSucceeded(Fingerprint fingerprint) {
                mHandler.obtainMessage(MSG_REFRESH_FINGERPRINT_TEMPLATES,
                        fingerprint.getFingerId(), 0).sendToTarget();
            }

            @Override
            public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString) {
                Toast.makeText(getActivity(), errString, Toast.LENGTH_SHORT);
            }
        };
        private final Handler mHandler = new Handler() {
            public void handleMessage(android.os.Message msg) {
                switch (msg.what) {
@@ -104,20 +152,7 @@ public class FingerprintSettings extends SettingsActivity {
            super.onCreate(savedInstanceState);
            mFingerprintManager = (FingerprintManager) getActivity().getSystemService(
                    Context.FINGERPRINT_SERVICE);
            mFingerprintManager.startListening(new FingerprintManagerReceiver() {
                @Override
                public void onRemoved(int fingerprintId) {
                    mHandler.obtainMessage(MSG_REFRESH_FINGERPRINT_TEMPLATES, fingerprintId, 0)
                            .sendToTarget();
                }
                @Override
                public void onProcessed(int fingerprintId) {
                    if (fingerprintId != 0) {
                        mHandler.obtainMessage(MSG_HIGHLIGHT_FINGERPRINT_ITEM, fingerprintId, 0)
                                .sendToTarget();
                    }
                }
            });
            mFingerprintManager.authenticate(null, mAuthCallback, null, 0);
        }

        protected void removeFingerprintPreference(int fingerprintId) {
@@ -181,15 +216,15 @@ public class FingerprintSettings extends SettingsActivity {

        private void addFingerprintItemPreferences(PreferenceGroup manageFingerprintCategory) {
            manageFingerprintCategory.removeAll();
            List<FingerprintItem> items = mFingerprintManager.getEnrolledFingerprints();
            final List<Fingerprint> items = mFingerprintManager.getEnrolledFingerprints();
            final int fingerprintCount = items.size();
            for (int i = 0; i < fingerprintCount; i++) {
                final FingerprintItem item = items.get(i);
                final Fingerprint item = items.get(i);
                FingerprintPreference pref = new FingerprintPreference(
                        manageFingerprintCategory.getContext());
                pref.setKey(genKey(item.id));
                pref.setTitle(item.name);
                pref.setFingerprintItem(item);
                pref.setKey(genKey(item.getFingerId()));
                pref.setTitle(item.getName());
                pref.setFingerprint(item);
                pref.setPersistent(false);
                manageFingerprintCategory.addPreference(pref);
                pref.setOnPreferenceChangeListener(this);
@@ -222,15 +257,14 @@ public class FingerprintSettings extends SettingsActivity {
                startActivityForResult(intent, ADD_FINGERPRINT_REQUEST);
            } else if (pref instanceof FingerprintPreference) {
                FingerprintPreference fpref = (FingerprintPreference) pref;
                final FingerprintItem item =fpref.getFingerprintItem();
                showRenameDeleteDialog(item.name, pref, item.id);
                final Fingerprint fp =fpref.getFingerprint();
                showRenameDeleteDialog(pref, fp);
                return super.onPreferenceTreeClick(preferenceScreen, pref);
            }
            return true;
        }

        private void showRenameDeleteDialog(final CharSequence name, Preference pref,
                final int fpId) {
        private void showRenameDeleteDialog(Preference pref, final Fingerprint fp) {
            final Activity activity = getActivity();
            AlertDialog dialog = new AlertDialog.Builder(activity)
                    .setView(R.layout.fingerprint_rename_dialog)
@@ -238,10 +272,11 @@ public class FingerprintSettings extends SettingsActivity {
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    String newName = mDialogTextField.getText().toString();
                                    final String newName = mDialogTextField.getText().toString();
                                    final CharSequence name = fp.getName();
                                    if (!newName.equals(name)) {
                                        Log.v(TAG, "Would rename " + name + " to " + newName);
                                        mFingerprintManager.rename(fpId, newName);
                                        if (DEBUG) Log.v(TAG, "rename " + name + " to " + newName);
                                        mFingerprintManager.rename(fp.getFingerId(), newName);
                                    }
                                    dialog.dismiss();
                                }
@@ -250,15 +285,15 @@ public class FingerprintSettings extends SettingsActivity {
                            new DialogInterface.OnClickListener() {
                                @Override
                                public void onClick(DialogInterface dialog, int which) {
                                    Log.v(TAG, "Removing fpId " + fpId);
                                    mFingerprintManager.remove(fpId);
                                    if (DEBUG) Log.v(TAG, "Removing fpId=" + fp.getFingerId());
                                    mFingerprintManager.remove(fp, mRemoveCallback);
                                    dialog.dismiss();
                                }
                            })
                    .create();
            dialog.show();
            mDialogTextField = (EditText) dialog.findViewById(R.id.fingerprint_rename_field);
            mDialogTextField.setText(name);
            mDialogTextField.setText(fp.getName());
            mDialogTextField.selectAll();
        }

@@ -282,7 +317,7 @@ public class FingerprintSettings extends SettingsActivity {

    public static class FingerprintPreference extends Preference {
        private static final int RESET_HIGHLIGHT_DELAY_MS = 500;
        private FingerprintItem mFingerprintItem;
        private Fingerprint mFingerprint;
        private View mView;
        private Drawable mHighlightDrawable;
        private Context mContext;
@@ -304,12 +339,12 @@ public class FingerprintSettings extends SettingsActivity {
            this(context, null);
        }

        public void setFingerprintItem(FingerprintItem item) {
            mFingerprintItem = item;
        public void setFingerprint(Fingerprint item) {
            mFingerprint = item;
        }

        public FingerprintItem getFingerprintItem() {
            return mFingerprintItem;
        public Fingerprint getFingerprint() {
            return mFingerprint;
        }

        private Drawable getHighlightDrawable() {
+3 −3
Original line number Diff line number Diff line
@@ -40,8 +40,8 @@ import android.preference.PreferenceScreen;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.security.KeyStore;
import android.service.fingerprint.Fingerprint;
import android.service.fingerprint.FingerprintManager;
import android.service.fingerprint.FingerprintManager.FingerprintItem;
import android.service.trust.TrustAgentService;
import android.telephony.TelephonyManager;
import android.telephony.SubscriptionManager;
@@ -341,8 +341,8 @@ public class SecuritySettings extends SettingsPreferenceFragment
        fingerprintPreference.setKey(KEY_FINGERPRINT_SETTINGS);
        fingerprintPreference.setTitle(R.string.security_settings_fingerprint_preference_title);
        Intent intent = new Intent();
        List<FingerprintItem> items = fpm.getEnrolledFingerprints();
        int fingerprintCount = items.size();
        final List<Fingerprint> items = fpm.getEnrolledFingerprints();
        final int fingerprintCount = items != null ? items.size() : 0;
        final String clazz;
        if (fingerprintCount > 0) {
            fingerprintPreference.setSummary(getResources().getQuantityString(