From d16c9b7c3100b7ba653dcd58db036500dd220896 Mon Sep 17 00:00:00 2001 From: Jim Miller Date: Tue, 24 Mar 2015 16:02:59 -0700 Subject: [PATCH] Update Settings to use new fingerprint API Bug 16487912 Change-Id: I99ac78f476d43f6b87f5dd20e597c51ed08d2c0e --- res/values/strings.xml | 19 +-- .../android/settings/ChooseLockGeneric.java | 29 +++-- .../android/settings/FingerprintEnroll.java | 116 ++++++++---------- .../android/settings/FingerprintSettings.java | 107 ++++++++++------ .../android/settings/SecuritySettings.java | 6 +- 5 files changed, 141 insertions(+), 136 deletions(-) diff --git a/res/values/strings.xml b/res/values/strings.xml index f4edc7a4a58..0b6a3b4c420 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -764,7 +764,8 @@ Fingerprint setup - + To use your fingerprint to unlock your screen or confirm purchases, we\'ll need to: \n\n\u2713 Set up your background screen lock method @@ -796,22 +797,6 @@ Add Next - - Partial fingerprint detected. Please try again. - - Fingerprint sensor is dirty. Please clean and try again. - - Finger moved to fast. Please try again. - - Finger moved to slow. Please try again. - - Unable to process. Try again. - - Hardware not available. - - Fingerprint can\'t be stored. Please remove an existing fingerprint. - - Fingerprint time out reached. Try again. Encryption diff --git a/src/com/android/settings/ChooseLockGeneric.java b/src/com/android/settings/ChooseLockGeneric.java index 6cec42068e1..b6f907e0324 100644 --- a/src/com/android/settings/ChooseLockGeneric.java +++ b/src/com/android/settings/ChooseLockGeneric.java @@ -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 diff --git a/src/com/android/settings/FingerprintEnroll.java b/src/com/android/settings/FingerprintEnroll.java index 376444eacbf..931fb9c6f72 100644 --- a/src/com/android/settings/FingerprintEnroll.java +++ b/src/com/android/settings/FingerprintEnroll.java @@ -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 onEnrollmentHelp(int helpMsgId, CharSequence helpString) { + setMessage(helpString); } @Override - public void onProcessed(int fingerprintId) { - if (DEBUG) Log.v(TAG, "onProcessed(id=" + fingerprintId + ")"); - } - - 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); + 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()) { diff --git a/src/com/android/settings/FingerprintSettings.java b/src/com/android/settings/FingerprintSettings.java index e7443e38601..db8706522a5 100644 --- a/src/com/android/settings/FingerprintSettings.java +++ b/src/com/android/settings/FingerprintSettings.java @@ -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 = "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 items = mFingerprintManager.getEnrolledFingerprints(); + final List 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() { diff --git a/src/com/android/settings/SecuritySettings.java b/src/com/android/settings/SecuritySettings.java index 1f6d50aef35..4ca21402294 100644 --- a/src/com/android/settings/SecuritySettings.java +++ b/src/com/android/settings/SecuritySettings.java @@ -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 items = fpm.getEnrolledFingerprints(); - int fingerprintCount = items.size(); + final List items = fpm.getEnrolledFingerprints(); + final int fingerprintCount = items != null ? items.size() : 0; final String clazz; if (fingerprintCount > 0) { fingerprintPreference.setSummary(getResources().getQuantityString(