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(