Loading res/values/strings.xml +2 −17 Original line number Diff line number Diff line Loading @@ -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 background screen lock method Loading Loading @@ -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> Loading src/com/android/settings/ChooseLockGeneric.java +17 −12 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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 Loading src/com/android/settings/FingerprintEnroll.java +48 −68 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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 Loading @@ -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; } } Loading @@ -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; } } Loading @@ -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) { Loading @@ -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); } Loading @@ -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); Loading @@ -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); } }; Loading Loading @@ -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()) { Loading src/com/android/settings/FingerprintSettings.java +71 −36 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"; Loading @@ -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) { Loading @@ -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) { Loading Loading @@ -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); Loading Loading @@ -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) Loading @@ -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(); } Loading @@ -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(); } Loading @@ -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; Loading @@ -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() { Loading src/com/android/settings/SecuritySettings.java +3 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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( Loading Loading
res/values/strings.xml +2 −17 Original line number Diff line number Diff line Loading @@ -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 background screen lock method Loading Loading @@ -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> Loading
src/com/android/settings/ChooseLockGeneric.java +17 −12 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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) { Loading Loading @@ -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 Loading
src/com/android/settings/FingerprintEnroll.java +48 −68 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading Loading @@ -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 Loading Loading @@ -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 Loading @@ -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; } } Loading @@ -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; } } Loading @@ -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) { Loading @@ -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); } Loading @@ -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); Loading @@ -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); } }; Loading Loading @@ -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()) { Loading
src/com/android/settings/FingerprintSettings.java +71 −36 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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"; Loading @@ -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) { Loading @@ -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) { Loading Loading @@ -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); Loading Loading @@ -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) Loading @@ -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(); } Loading @@ -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(); } Loading @@ -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; Loading @@ -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() { Loading
src/com/android/settings/SecuritySettings.java +3 −3 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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( Loading