19218687e4baaf0226ef16b58f78123d979711e5dJim Miller/* 29218687e4baaf0226ef16b58f78123d979711e5dJim Miller * Copyright (C) 2015 The Android Open Source Project 39218687e4baaf0226ef16b58f78123d979711e5dJim Miller * 49218687e4baaf0226ef16b58f78123d979711e5dJim Miller * Licensed under the Apache License, Version 2.0 (the "License"); 59218687e4baaf0226ef16b58f78123d979711e5dJim Miller * you may not use this file except in compliance with the License. 69218687e4baaf0226ef16b58f78123d979711e5dJim Miller * You may obtain a copy of the License at 79218687e4baaf0226ef16b58f78123d979711e5dJim Miller * 89218687e4baaf0226ef16b58f78123d979711e5dJim Miller * http://www.apache.org/licenses/LICENSE-2.0 99218687e4baaf0226ef16b58f78123d979711e5dJim Miller * 109218687e4baaf0226ef16b58f78123d979711e5dJim Miller * Unless required by applicable law or agreed to in writing, software 119218687e4baaf0226ef16b58f78123d979711e5dJim Miller * distributed under the License is distributed on an "AS IS" BASIS, 129218687e4baaf0226ef16b58f78123d979711e5dJim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139218687e4baaf0226ef16b58f78123d979711e5dJim Miller * See the License for the specific language governing permissions and 149218687e4baaf0226ef16b58f78123d979711e5dJim Miller * limitations under the License. 159218687e4baaf0226ef16b58f78123d979711e5dJim Miller */ 169218687e4baaf0226ef16b58f78123d979711e5dJim Miller 175ad75f07b1861b802b75c720830db260b4f93417Jorim Jaggipackage com.android.settings.fingerprint; 189218687e4baaf0226ef16b58f78123d979711e5dJim Miller 199218687e4baaf0226ef16b58f78123d979711e5dJim Miller 204dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport android.annotation.Nullable; 219218687e4baaf0226ef16b58f78123d979711e5dJim Millerimport android.app.Activity; 229218687e4baaf0226ef16b58f78123d979711e5dJim Millerimport android.app.AlertDialog; 23f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinekimport android.app.Dialog; 24f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinekimport android.app.DialogFragment; 25e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Moralesimport android.app.admin.DevicePolicyManager; 264dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport android.content.ActivityNotFoundException; 279218687e4baaf0226ef16b58f78123d979711e5dJim Millerimport android.content.Context; 289218687e4baaf0226ef16b58f78123d979711e5dJim Millerimport android.content.DialogInterface; 299218687e4baaf0226ef16b58f78123d979711e5dJim Millerimport android.content.Intent; 304dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport android.graphics.Typeface; 314f6f7c865f25f478e5198031d419b498bdeb7ffaJim Millerimport android.graphics.drawable.Drawable; 324dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport android.hardware.fingerprint.Fingerprint; 334dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport android.hardware.fingerprint.FingerprintManager; 344dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport android.hardware.fingerprint.FingerprintManager.AuthenticationCallback; 354dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport android.hardware.fingerprint.FingerprintManager.AuthenticationResult; 364dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport android.hardware.fingerprint.FingerprintManager.RemovalCallback; 379218687e4baaf0226ef16b58f78123d979711e5dJim Millerimport android.os.Bundle; 388e056115eead7040584eda8c78b069998f0a9f2bJim Millerimport android.os.CancellationSignal; 394f6f7c865f25f478e5198031d419b498bdeb7ffaJim Millerimport android.os.Handler; 409218687e4baaf0226ef16b58f78123d979711e5dJim Millerimport android.preference.Preference; 419218687e4baaf0226ef16b58f78123d979711e5dJim Millerimport android.preference.Preference.OnPreferenceChangeListener; 429218687e4baaf0226ef16b58f78123d979711e5dJim Millerimport android.preference.PreferenceGroup; 439218687e4baaf0226ef16b58f78123d979711e5dJim Millerimport android.preference.PreferenceScreen; 444dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport android.text.Annotation; 454dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport android.text.SpannableString; 464dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport android.text.SpannableStringBuilder; 474dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport android.text.TextPaint; 484dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport android.text.method.LinkMovementMethod; 494dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport android.text.style.URLSpan; 504f6f7c865f25f478e5198031d419b498bdeb7ffaJim Millerimport android.util.AttributeSet; 519218687e4baaf0226ef16b58f78123d979711e5dJim Millerimport android.util.Log; 524dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport android.view.LayoutInflater; 534f6f7c865f25f478e5198031d419b498bdeb7ffaJim Millerimport android.view.View; 54a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Millerimport android.view.WindowManager; 559218687e4baaf0226ef16b58f78123d979711e5dJim Millerimport android.widget.EditText; 564dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport android.widget.TextView; 57d16c9b7c3100b7ba653dcd58db036500dd220896Jim Millerimport android.widget.Toast; 589218687e4baaf0226ef16b58f78123d979711e5dJim Miller 598a963babe2e36b7a41f77b8d2598c97658196e58Chris Wrenimport com.android.internal.logging.MetricsLogger; 605ad75f07b1861b802b75c720830db260b4f93417Jorim Jaggiimport com.android.settings.ChooseLockGeneric; 615ad75f07b1861b802b75c720830db260b4f93417Jorim Jaggiimport com.android.settings.ChooseLockSettingsHelper; 624dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport com.android.settings.HelpUtils; 635ad75f07b1861b802b75c720830db260b4f93417Jorim Jaggiimport com.android.settings.R; 645ad75f07b1861b802b75c720830db260b4f93417Jorim Jaggiimport com.android.settings.SettingsPreferenceFragment; 654dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggiimport com.android.settings.SubSettings; 669218687e4baaf0226ef16b58f78123d979711e5dJim Miller 679218687e4baaf0226ef16b58f78123d979711e5dJim Millerimport java.util.List; 689218687e4baaf0226ef16b58f78123d979711e5dJim Miller 699218687e4baaf0226ef16b58f78123d979711e5dJim Miller/** 709218687e4baaf0226ef16b58f78123d979711e5dJim Miller * Settings screen for fingerprints 719218687e4baaf0226ef16b58f78123d979711e5dJim Miller */ 724dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggipublic class FingerprintSettings extends SubSettings { 73457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller 74e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales /** 75457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller * Used by the choose fingerprint wizard to indicate the wizard is 76e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales * finished, and each activity in the wizard should finish. 77e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales * <p> 78e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales * Previously, each activity in the wizard would finish itself after 79e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales * starting the next activity. However, this leads to broken 'Back' 80e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales * behavior. So, now an activity does not finish itself until it gets this 81e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales * result. 82e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales */ 83457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller protected static final int RESULT_FINISHED = RESULT_FIRST_USER; 84457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller 85457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller /** 86457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller * Used by the enrolling screen during setup wizard to skip over setting up fingerprint, which 87457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller * will be useful if the user accidentally entered this flow. 88457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller */ 89457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller protected static final int RESULT_SKIP = RESULT_FIRST_USER + 1; 90457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller 91457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller /** 92457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller * Like {@link #RESULT_FINISHED} except this one indicates enrollment failed because the 93457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller * device was left idle. This is used to clear the credential token to require the user to 94457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller * re-enter their pin/pattern/password before continuing. 95457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller */ 96457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller protected static final int RESULT_TIMEOUT = RESULT_FIRST_USER + 2; 97457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller 988e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller private static final long LOCKOUT_DURATION = 30000; // time we have to wait for fp to reset, ms 999218687e4baaf0226ef16b58f78123d979711e5dJim Miller 1009218687e4baaf0226ef16b58f78123d979711e5dJim Miller @Override 1019218687e4baaf0226ef16b58f78123d979711e5dJim Miller public Intent getIntent() { 1029218687e4baaf0226ef16b58f78123d979711e5dJim Miller Intent modIntent = new Intent(super.getIntent()); 1039218687e4baaf0226ef16b58f78123d979711e5dJim Miller modIntent.putExtra(EXTRA_SHOW_FRAGMENT, FingerprintSettingsFragment.class.getName()); 1049218687e4baaf0226ef16b58f78123d979711e5dJim Miller return modIntent; 1059218687e4baaf0226ef16b58f78123d979711e5dJim Miller } 1069218687e4baaf0226ef16b58f78123d979711e5dJim Miller 1079218687e4baaf0226ef16b58f78123d979711e5dJim Miller @Override 1089218687e4baaf0226ef16b58f78123d979711e5dJim Miller protected boolean isValidFragment(String fragmentName) { 1099218687e4baaf0226ef16b58f78123d979711e5dJim Miller if (FingerprintSettingsFragment.class.getName().equals(fragmentName)) return true; 1109218687e4baaf0226ef16b58f78123d979711e5dJim Miller return false; 1119218687e4baaf0226ef16b58f78123d979711e5dJim Miller } 1129218687e4baaf0226ef16b58f78123d979711e5dJim Miller 1139218687e4baaf0226ef16b58f78123d979711e5dJim Miller @Override 1149218687e4baaf0226ef16b58f78123d979711e5dJim Miller public void onCreate(Bundle savedInstanceState) { 1159218687e4baaf0226ef16b58f78123d979711e5dJim Miller super.onCreate(savedInstanceState); 1169218687e4baaf0226ef16b58f78123d979711e5dJim Miller CharSequence msg = getText(R.string.security_settings_fingerprint_preference_title); 1179218687e4baaf0226ef16b58f78123d979711e5dJim Miller setTitle(msg); 1189218687e4baaf0226ef16b58f78123d979711e5dJim Miller } 1199218687e4baaf0226ef16b58f78123d979711e5dJim Miller 1209218687e4baaf0226ef16b58f78123d979711e5dJim Miller public static class FingerprintSettingsFragment extends SettingsPreferenceFragment 121f516e7dde0074416dbf51650cbfb9cc763027b27Julia Reynolds implements OnPreferenceChangeListener { 122a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller private static final int MAX_RETRY_ATTEMPTS = 20; 123a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller private static final int RESET_HIGHLIGHT_DELAY_MS = 500; 124a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller 1259218687e4baaf0226ef16b58f78123d979711e5dJim Miller private static final String TAG = "FingerprintSettings"; 1268a7dea562087a58ae8eb0699f262d7114db719bcJim Miller private static final String KEY_FINGERPRINT_ITEM_PREFIX = "key_fingerprint_item"; 1279218687e4baaf0226ef16b58f78123d979711e5dJim Miller private static final String KEY_FINGERPRINT_ADD = "key_fingerprint_add"; 1289218687e4baaf0226ef16b58f78123d979711e5dJim Miller private static final String KEY_FINGERPRINT_ENABLE_KEYGUARD_TOGGLE = 1299218687e4baaf0226ef16b58f78123d979711e5dJim Miller "fingerprint_enable_keyguard_toggle"; 130887c90d8af1b9cbac51e0febfa33057a64a28ee5Andres Morales private static final String KEY_LAUNCHED_CONFIRM = "launched_confirm"; 1319218687e4baaf0226ef16b58f78123d979711e5dJim Miller 1324f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller private static final int MSG_REFRESH_FINGERPRINT_TEMPLATES = 1000; 133a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller private static final int MSG_FINGER_AUTH_SUCCESS = 1001; 134a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller private static final int MSG_FINGER_AUTH_FAIL = 1002; 135fa47bc02900d407e1a730039e94221c2efc160d0Jim Miller private static final int MSG_FINGER_AUTH_ERROR = 1003; 136fa47bc02900d407e1a730039e94221c2efc160d0Jim Miller private static final int MSG_FINGER_AUTH_HELP = 1004; 1374f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller 138e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales private static final int CONFIRM_REQUEST = 101; 139e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales private static final int CHOOSE_LOCK_GENERIC_REQUEST = 102; 140e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales 1419218687e4baaf0226ef16b58f78123d979711e5dJim Miller private static final int ADD_FINGERPRINT_REQUEST = 10; 1429218687e4baaf0226ef16b58f78123d979711e5dJim Miller 143d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller protected static final boolean DEBUG = true; 1449218687e4baaf0226ef16b58f78123d979711e5dJim Miller 1459218687e4baaf0226ef16b58f78123d979711e5dJim Miller private FingerprintManager mFingerprintManager; 1468e056115eead7040584eda8c78b069998f0a9f2bJim Miller private CancellationSignal mFingerprintCancel; 1478e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller private boolean mInFingerprintLockout; 148e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales private byte[] mToken; 149887c90d8af1b9cbac51e0febfa33057a64a28ee5Andres Morales private boolean mLaunchedConfirm; 150a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller private Drawable mHighlightDrawable; 1518e056115eead7040584eda8c78b069998f0a9f2bJim Miller 152d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller private AuthenticationCallback mAuthCallback = new AuthenticationCallback() { 153d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller @Override 154d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller public void onAuthenticationSucceeded(AuthenticationResult result) { 155a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller int fingerId = result.getFingerprint().getFingerId(); 156a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller mHandler.obtainMessage(MSG_FINGER_AUTH_SUCCESS, fingerId, 0).sendToTarget(); 157d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller } 158d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller 159e9785ac1e4b779b6119460a5cdc71bce4d6563b9Jim Miller @Override 1608e056115eead7040584eda8c78b069998f0a9f2bJim Miller public void onAuthenticationFailed() { 161a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller mHandler.obtainMessage(MSG_FINGER_AUTH_FAIL).sendToTarget(); 1628e056115eead7040584eda8c78b069998f0a9f2bJim Miller }; 1638e056115eead7040584eda8c78b069998f0a9f2bJim Miller 164d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller @Override 165d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller public void onAuthenticationError(int errMsgId, CharSequence errString) { 166fa47bc02900d407e1a730039e94221c2efc160d0Jim Miller mHandler.obtainMessage(MSG_FINGER_AUTH_ERROR, errMsgId, 0, errString) 167fa47bc02900d407e1a730039e94221c2efc160d0Jim Miller .sendToTarget(); 168d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller } 169d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller 170d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller @Override 171d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) { 172fa47bc02900d407e1a730039e94221c2efc160d0Jim Miller mHandler.obtainMessage(MSG_FINGER_AUTH_HELP, helpMsgId, 0, helpString) 173fa47bc02900d407e1a730039e94221c2efc160d0Jim Miller .sendToTarget(); 174d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller } 175d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller }; 176d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller private RemovalCallback mRemoveCallback = new RemovalCallback() { 177d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller 178d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller @Override 179d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller public void onRemovalSucceeded(Fingerprint fingerprint) { 180d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller mHandler.obtainMessage(MSG_REFRESH_FINGERPRINT_TEMPLATES, 181d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller fingerprint.getFingerId(), 0).sendToTarget(); 182d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller } 183d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller 184d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller @Override 185d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString) { 186622142ce9d8c6359d27b44827551c665c800347cJim Miller final Activity activity = getActivity(); 187622142ce9d8c6359d27b44827551c665c800347cJim Miller if (activity != null) { 188622142ce9d8c6359d27b44827551c665c800347cJim Miller Toast.makeText(activity, errString, Toast.LENGTH_SHORT); 189622142ce9d8c6359d27b44827551c665c800347cJim Miller } 190d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller } 191d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller }; 1924f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller private final Handler mHandler = new Handler() { 193e9785ac1e4b779b6119460a5cdc71bce4d6563b9Jim Miller @Override 1944f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller public void handleMessage(android.os.Message msg) { 1954f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller switch (msg.what) { 1964f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller case MSG_REFRESH_FINGERPRINT_TEMPLATES: 1974f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller removeFingerprintPreference(msg.arg1); 1985adada6083c1fb5e520e3044698b03ee29772dabJim Miller updateAddPreference(); 1991e2433693adbe2cca0feab79c18ae5be9e43d167Jorim Jaggi retryFingerprint(); 2004f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller break; 201a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller case MSG_FINGER_AUTH_SUCCESS: 202fa47bc02900d407e1a730039e94221c2efc160d0Jim Miller mFingerprintCancel = null; 2034f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller highlightFingerprintItem(msg.arg1); 2048e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller retryFingerprint(); 205a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller break; 206a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller case MSG_FINGER_AUTH_FAIL: 2078e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller // No action required... fingerprint will allow up to 5 of these 2084f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller break; 2098e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller case MSG_FINGER_AUTH_ERROR: 2108e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller handleError(msg.arg1 /* errMsgId */, (CharSequence) msg.obj /* errStr */ ); 211fa47bc02900d407e1a730039e94221c2efc160d0Jim Miller break; 212fa47bc02900d407e1a730039e94221c2efc160d0Jim Miller case MSG_FINGER_AUTH_HELP: { 2138e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller // Not used 214fa47bc02900d407e1a730039e94221c2efc160d0Jim Miller } 215fa47bc02900d407e1a730039e94221c2efc160d0Jim Miller break; 2164f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller } 2174f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller }; 2184f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller }; 2199218687e4baaf0226ef16b58f78123d979711e5dJim Miller 2208e056115eead7040584eda8c78b069998f0a9f2bJim Miller private void stopFingerprint() { 2218e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller if (mFingerprintCancel != null && !mFingerprintCancel.isCanceled()) { 2228e056115eead7040584eda8c78b069998f0a9f2bJim Miller mFingerprintCancel.cancel(); 2238e056115eead7040584eda8c78b069998f0a9f2bJim Miller } 2248e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller mFingerprintCancel = null; 2258e056115eead7040584eda8c78b069998f0a9f2bJim Miller } 2268e056115eead7040584eda8c78b069998f0a9f2bJim Miller 2278e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller /** 2288e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller * @param errMsgId 2298e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller */ 2308e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller protected void handleError(int errMsgId, CharSequence msg) { 2318e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller mFingerprintCancel = null; 2328e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller switch (errMsgId) { 2338e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller case FingerprintManager.FINGERPRINT_ERROR_CANCELED: 2348e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller return; // Only happens if we get preempted by another activity. Ignored. 2358e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller case FingerprintManager.FINGERPRINT_ERROR_LOCKOUT: 2368e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller mInFingerprintLockout = true; 2378e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller // We've been locked out. Reset after 30s. 2388e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller if (!mHandler.hasCallbacks(mFingerprintLockoutReset)) { 2398e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller mHandler.postDelayed(mFingerprintLockoutReset, 2408e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller LOCKOUT_DURATION); 2418e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller } 2428e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller // Fall through to show message 2438e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller default: 2448e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller // Activity can be null on a screen rotation. 2458e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller final Activity activity = getActivity(); 2468e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller if (activity != null) { 2478e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller Toast.makeText(activity, msg , Toast.LENGTH_SHORT); 2488e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller } 2498e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller break; 2508e056115eead7040584eda8c78b069998f0a9f2bJim Miller } 2518e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller retryFingerprint(); // start again 2528e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller } 2538e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller 2548e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller private void retryFingerprint() { 2558e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller if (!mInFingerprintLockout) { 2568e056115eead7040584eda8c78b069998f0a9f2bJim Miller mFingerprintCancel = new CancellationSignal(); 257fa47bc02900d407e1a730039e94221c2efc160d0Jim Miller mFingerprintManager.authenticate(null, mFingerprintCancel, 0 /* flags */, 258fa47bc02900d407e1a730039e94221c2efc160d0Jim Miller mAuthCallback, null); 2598e056115eead7040584eda8c78b069998f0a9f2bJim Miller } 2608e056115eead7040584eda8c78b069998f0a9f2bJim Miller } 2618e056115eead7040584eda8c78b069998f0a9f2bJim Miller 2629218687e4baaf0226ef16b58f78123d979711e5dJim Miller @Override 2638a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren protected int getMetricsCategory() { 2648a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren return MetricsLogger.FINGERPRINT; 2658a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren } 2668a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren 2678a963babe2e36b7a41f77b8d2598c97658196e58Chris Wren @Override 2689218687e4baaf0226ef16b58f78123d979711e5dJim Miller public void onCreate(Bundle savedInstanceState) { 2699218687e4baaf0226ef16b58f78123d979711e5dJim Miller super.onCreate(savedInstanceState); 270e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales if (savedInstanceState != null) { 271e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales mToken = savedInstanceState.getByteArray( 272e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); 273887c90d8af1b9cbac51e0febfa33057a64a28ee5Andres Morales mLaunchedConfirm = savedInstanceState.getBoolean( 274887c90d8af1b9cbac51e0febfa33057a64a28ee5Andres Morales KEY_LAUNCHED_CONFIRM, false); 275e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales } 276e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales 277a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller Activity activity = getActivity(); 278a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller mFingerprintManager = (FingerprintManager) activity.getSystemService( 2799218687e4baaf0226ef16b58f78123d979711e5dJim Miller Context.FINGERPRINT_SERVICE); 280e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales 281e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales // Need to authenticate a session token if none 282887c90d8af1b9cbac51e0febfa33057a64a28ee5Andres Morales if (mToken == null && mLaunchedConfirm == false) { 283887c90d8af1b9cbac51e0febfa33057a64a28ee5Andres Morales mLaunchedConfirm = true; 284e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales launchChooseOrConfirmLock(); 285e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales } 2869218687e4baaf0226ef16b58f78123d979711e5dJim Miller } 2879218687e4baaf0226ef16b58f78123d979711e5dJim Miller 2884dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi @Override 2894dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi public void onViewCreated(View view, @Nullable Bundle savedInstanceState) { 2904dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi super.onViewCreated(view, savedInstanceState); 2914dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi TextView v = (TextView) LayoutInflater.from(view.getContext()).inflate( 2924dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi R.layout.fingerprint_settings_footer, null); 2934dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi v.setText(LearnMoreSpan.linkify(getText(isFingerprintDisabled() 2944dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi ? R.string.security_settings_fingerprint_enroll_disclaimer_lockscreen_disabled 2954dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi : R.string.security_settings_fingerprint_enroll_disclaimer), 2964dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi getString(getHelpResource()))); 2974dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi v.setMovementMethod(new LinkMovementMethod()); 2984dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi getListView().addFooterView(v); 2994dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi getListView().setFooterDividersEnabled(false); 3004dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi } 3014dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi 3024dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi private boolean isFingerprintDisabled() { 3034dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi final DevicePolicyManager dpm = 3044dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); 3054dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi return dpm != null && (dpm.getKeyguardDisabledFeatures(null) 3064dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0; 3074dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi } 3084dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi 3094f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller protected void removeFingerprintPreference(int fingerprintId) { 3104f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller String name = genKey(fingerprintId); 3110dbeeda0532518665389d458155322f69e603686Jorim Jaggi Preference prefToRemove = findPreference(name); 3124f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller if (prefToRemove != null) { 3130dbeeda0532518665389d458155322f69e603686Jorim Jaggi if (!getPreferenceScreen().removePreference(prefToRemove)) { 3144f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller Log.w(TAG, "Failed to remove preference with key " + name); 3154f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller } 3164f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller } else { 3174f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller Log.w(TAG, "Can't find preference to remove: " + name); 3184f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller } 3194f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller } 3204f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller 3219218687e4baaf0226ef16b58f78123d979711e5dJim Miller /** 3229218687e4baaf0226ef16b58f78123d979711e5dJim Miller * Important! 3239218687e4baaf0226ef16b58f78123d979711e5dJim Miller * 3249218687e4baaf0226ef16b58f78123d979711e5dJim Miller * Don't forget to update the SecuritySearchIndexProvider if you are doing any change in the 3259218687e4baaf0226ef16b58f78123d979711e5dJim Miller * logic or adding/removing preferences here. 3269218687e4baaf0226ef16b58f78123d979711e5dJim Miller */ 3279218687e4baaf0226ef16b58f78123d979711e5dJim Miller private PreferenceScreen createPreferenceHierarchy() { 3289218687e4baaf0226ef16b58f78123d979711e5dJim Miller PreferenceScreen root = getPreferenceScreen(); 3299218687e4baaf0226ef16b58f78123d979711e5dJim Miller if (root != null) { 3309218687e4baaf0226ef16b58f78123d979711e5dJim Miller root.removeAll(); 3319218687e4baaf0226ef16b58f78123d979711e5dJim Miller } 3329218687e4baaf0226ef16b58f78123d979711e5dJim Miller addPreferencesFromResource(R.xml.security_settings_fingerprint); 3339218687e4baaf0226ef16b58f78123d979711e5dJim Miller root = getPreferenceScreen(); 3344dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi addFingerprintItemPreferences(root); 3359218687e4baaf0226ef16b58f78123d979711e5dJim Miller return root; 3369218687e4baaf0226ef16b58f78123d979711e5dJim Miller } 3379218687e4baaf0226ef16b58f78123d979711e5dJim Miller 3384dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi private void addFingerprintItemPreferences(PreferenceGroup root) { 3394dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi root.removeAll(); 340d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller final List<Fingerprint> items = mFingerprintManager.getEnrolledFingerprints(); 3419218687e4baaf0226ef16b58f78123d979711e5dJim Miller final int fingerprintCount = items.size(); 3429218687e4baaf0226ef16b58f78123d979711e5dJim Miller for (int i = 0; i < fingerprintCount; i++) { 343d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller final Fingerprint item = items.get(i); 3444dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi FingerprintPreference pref = new FingerprintPreference(root.getContext()); 345d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller pref.setKey(genKey(item.getFingerId())); 346d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller pref.setTitle(item.getName()); 347d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller pref.setFingerprint(item); 3484f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller pref.setPersistent(false); 3494dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi root.addPreference(pref); 3509218687e4baaf0226ef16b58f78123d979711e5dJim Miller pref.setOnPreferenceChangeListener(this); 3519218687e4baaf0226ef16b58f78123d979711e5dJim Miller } 3524dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi Preference addPreference = new Preference(root.getContext()); 3539218687e4baaf0226ef16b58f78123d979711e5dJim Miller addPreference.setKey(KEY_FINGERPRINT_ADD); 3549218687e4baaf0226ef16b58f78123d979711e5dJim Miller addPreference.setTitle(R.string.fingerprint_add_title); 3554dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi addPreference.setIcon(R.drawable.ic_add_24dp); 3564dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi root.addPreference(addPreference); 3579218687e4baaf0226ef16b58f78123d979711e5dJim Miller addPreference.setOnPreferenceChangeListener(this); 3585adada6083c1fb5e520e3044698b03ee29772dabJim Miller updateAddPreference(); 3595adada6083c1fb5e520e3044698b03ee29772dabJim Miller } 3605adada6083c1fb5e520e3044698b03ee29772dabJim Miller 3615adada6083c1fb5e520e3044698b03ee29772dabJim Miller private void updateAddPreference() { 3625adada6083c1fb5e520e3044698b03ee29772dabJim Miller /* Disable preference if too many fingerprints added */ 3635adada6083c1fb5e520e3044698b03ee29772dabJim Miller final int max = getContext().getResources().getInteger( 3645adada6083c1fb5e520e3044698b03ee29772dabJim Miller com.android.internal.R.integer.config_fingerprintMaxTemplatesPerUser); 3655adada6083c1fb5e520e3044698b03ee29772dabJim Miller boolean tooMany = mFingerprintManager.getEnrolledFingerprints().size() >= max; 3665adada6083c1fb5e520e3044698b03ee29772dabJim Miller CharSequence maxSummary = tooMany ? 3675adada6083c1fb5e520e3044698b03ee29772dabJim Miller getContext().getString(R.string.fingerprint_add_max, max) : ""; 3685adada6083c1fb5e520e3044698b03ee29772dabJim Miller Preference addPreference = findPreference(KEY_FINGERPRINT_ADD); 3695adada6083c1fb5e520e3044698b03ee29772dabJim Miller addPreference.setSummary(maxSummary); 3705adada6083c1fb5e520e3044698b03ee29772dabJim Miller addPreference.setEnabled(!tooMany); 3719218687e4baaf0226ef16b58f78123d979711e5dJim Miller } 3729218687e4baaf0226ef16b58f78123d979711e5dJim Miller 3734f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller private static String genKey(int id) { 3748a7dea562087a58ae8eb0699f262d7114db719bcJim Miller return KEY_FINGERPRINT_ITEM_PREFIX + "_" + id; 3754f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller } 3764f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller 3779218687e4baaf0226ef16b58f78123d979711e5dJim Miller @Override 3789218687e4baaf0226ef16b58f78123d979711e5dJim Miller public void onResume() { 3799218687e4baaf0226ef16b58f78123d979711e5dJim Miller super.onResume(); 3809218687e4baaf0226ef16b58f78123d979711e5dJim Miller // Make sure we reload the preference hierarchy since fingerprints may be added, 3819218687e4baaf0226ef16b58f78123d979711e5dJim Miller // deleted or renamed. 382a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller updatePreferences(); 383a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller } 384e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales 385a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller private void updatePreferences() { 386a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller createPreferenceHierarchy(); 3878e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller retryFingerprint(); 3888e056115eead7040584eda8c78b069998f0a9f2bJim Miller } 3898e056115eead7040584eda8c78b069998f0a9f2bJim Miller 3908e056115eead7040584eda8c78b069998f0a9f2bJim Miller @Override 3918e056115eead7040584eda8c78b069998f0a9f2bJim Miller public void onPause() { 3928e056115eead7040584eda8c78b069998f0a9f2bJim Miller super.onPause(); 3938e056115eead7040584eda8c78b069998f0a9f2bJim Miller stopFingerprint(); 3949218687e4baaf0226ef16b58f78123d979711e5dJim Miller } 3959218687e4baaf0226ef16b58f78123d979711e5dJim Miller 3969218687e4baaf0226ef16b58f78123d979711e5dJim Miller @Override 397e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales public void onSaveInstanceState(final Bundle outState) { 398e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales outState.putByteArray(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, 399e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales mToken); 400887c90d8af1b9cbac51e0febfa33057a64a28ee5Andres Morales outState.putBoolean(KEY_LAUNCHED_CONFIRM, mLaunchedConfirm); 401e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales } 402e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales 403e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales @Override 4049218687e4baaf0226ef16b58f78123d979711e5dJim Miller public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen, Preference pref) { 4059218687e4baaf0226ef16b58f78123d979711e5dJim Miller final String key = pref.getKey(); 4069218687e4baaf0226ef16b58f78123d979711e5dJim Miller if (KEY_FINGERPRINT_ADD.equals(key)) { 4079218687e4baaf0226ef16b58f78123d979711e5dJim Miller Intent intent = new Intent(); 4085ad75f07b1861b802b75c720830db260b4f93417Jorim Jaggi intent.setClassName("com.android.settings", 4095ad75f07b1861b802b75c720830db260b4f93417Jorim Jaggi FingerprintEnrollEnrolling.class.getName()); 41055af42dce53fff7b4a878dde1d1ca0f752f88f9eAndres Morales intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN, mToken); 4119218687e4baaf0226ef16b58f78123d979711e5dJim Miller startActivityForResult(intent, ADD_FINGERPRINT_REQUEST); 4124f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller } else if (pref instanceof FingerprintPreference) { 4134f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller FingerprintPreference fpref = (FingerprintPreference) pref; 414d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller final Fingerprint fp =fpref.getFingerprint(); 415f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek showRenameDeleteDialog(fp); 4169218687e4baaf0226ef16b58f78123d979711e5dJim Miller return super.onPreferenceTreeClick(preferenceScreen, pref); 4179218687e4baaf0226ef16b58f78123d979711e5dJim Miller } 4189218687e4baaf0226ef16b58f78123d979711e5dJim Miller return true; 4199218687e4baaf0226ef16b58f78123d979711e5dJim Miller } 4209218687e4baaf0226ef16b58f78123d979711e5dJim Miller 421f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek private void showRenameDeleteDialog(final Fingerprint fp) { 422b83cbe202bd56cf542d898837474757dca3625f2Jorim Jaggi RenameDeleteDialog renameDeleteDialog = new RenameDeleteDialog(); 423f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek Bundle args = new Bundle(); 424f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek args.putParcelable("fingerprint", fp); 425f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek renameDeleteDialog.setArguments(args); 426f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek renameDeleteDialog.setTargetFragment(this, 0); 427f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek renameDeleteDialog.show(getFragmentManager(), RenameDeleteDialog.class.getName()); 4289218687e4baaf0226ef16b58f78123d979711e5dJim Miller } 4299218687e4baaf0226ef16b58f78123d979711e5dJim Miller 4309218687e4baaf0226ef16b58f78123d979711e5dJim Miller @Override 4319218687e4baaf0226ef16b58f78123d979711e5dJim Miller public boolean onPreferenceChange(Preference preference, Object value) { 4329218687e4baaf0226ef16b58f78123d979711e5dJim Miller boolean result = true; 4339218687e4baaf0226ef16b58f78123d979711e5dJim Miller final String key = preference.getKey(); 4349218687e4baaf0226ef16b58f78123d979711e5dJim Miller if (KEY_FINGERPRINT_ENABLE_KEYGUARD_TOGGLE.equals(key)) { 4359218687e4baaf0226ef16b58f78123d979711e5dJim Miller // TODO 4369218687e4baaf0226ef16b58f78123d979711e5dJim Miller } else { 4379218687e4baaf0226ef16b58f78123d979711e5dJim Miller Log.v(TAG, "Unknown key:" + key); 4389218687e4baaf0226ef16b58f78123d979711e5dJim Miller } 4399218687e4baaf0226ef16b58f78123d979711e5dJim Miller return result; 4409218687e4baaf0226ef16b58f78123d979711e5dJim Miller } 4419218687e4baaf0226ef16b58f78123d979711e5dJim Miller 4429218687e4baaf0226ef16b58f78123d979711e5dJim Miller @Override 4439218687e4baaf0226ef16b58f78123d979711e5dJim Miller protected int getHelpResource() { 4444dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi return R.string.help_url_fingerprint; 4459218687e4baaf0226ef16b58f78123d979711e5dJim Miller } 446e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales 447e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales @Override 448e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales public void onActivityResult(int requestCode, int resultCode, Intent data) { 449e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales super.onActivityResult(requestCode, resultCode, data); 450e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales if (requestCode == CHOOSE_LOCK_GENERIC_REQUEST 451e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales || requestCode == CONFIRM_REQUEST) { 452e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales if (resultCode == RESULT_FINISHED || resultCode == RESULT_OK) { 453e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales // The lock pin/pattern/password was set. Start enrolling! 454e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales if (data != null) { 455e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales mToken = data.getByteArrayExtra( 456e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE_TOKEN); 457e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales } 458e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales } 459457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller } else if (requestCode == ADD_FINGERPRINT_REQUEST) { 460457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller if (resultCode == RESULT_TIMEOUT) { 461457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller Activity activity = getActivity(); 462457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller activity.setResult(RESULT_TIMEOUT); 463457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller activity.finish(); 464457904634cdb657f1aff2b7da8cd7be68412e299Jim Miller } 465e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales } 466e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales 467e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales if (mToken == null) { 468e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales // Didn't get an authentication, finishing 469e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales getActivity().finish(); 470e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales } 471e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales } 472e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales 473e9785ac1e4b779b6119460a5cdc71bce4d6563b9Jim Miller @Override 474e9785ac1e4b779b6119460a5cdc71bce4d6563b9Jim Miller public void onDestroy() { 475e9785ac1e4b779b6119460a5cdc71bce4d6563b9Jim Miller super.onDestroy(); 476efaa19d97d4aba1897357971af4c0991af71dbbdJim Miller if (getActivity().isFinishing()) { 477efaa19d97d4aba1897357971af4c0991af71dbbdJim Miller int result = mFingerprintManager.postEnroll(); 478efaa19d97d4aba1897357971af4c0991af71dbbdJim Miller if (result < 0) { 479efaa19d97d4aba1897357971af4c0991af71dbbdJim Miller Log.w(TAG, "postEnroll failed: result = " + result); 480efaa19d97d4aba1897357971af4c0991af71dbbdJim Miller } 481e9785ac1e4b779b6119460a5cdc71bce4d6563b9Jim Miller } 482e9785ac1e4b779b6119460a5cdc71bce4d6563b9Jim Miller } 483e9785ac1e4b779b6119460a5cdc71bce4d6563b9Jim Miller 484a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller private Drawable getHighlightDrawable() { 485a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller if (mHighlightDrawable == null) { 486622142ce9d8c6359d27b44827551c665c800347cJim Miller final Activity activity = getActivity(); 487622142ce9d8c6359d27b44827551c665c800347cJim Miller if (activity != null) { 488622142ce9d8c6359d27b44827551c665c800347cJim Miller mHighlightDrawable = activity.getDrawable(R.drawable.preference_highlight); 489622142ce9d8c6359d27b44827551c665c800347cJim Miller } 490a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller } 491a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller return mHighlightDrawable; 492a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller } 493a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller 494a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller private void highlightFingerprintItem(int fpId) { 495a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller String prefName = genKey(fpId); 496622142ce9d8c6359d27b44827551c665c800347cJim Miller FingerprintPreference fpref = (FingerprintPreference) findPreference(prefName); 497a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller final Drawable highlight = getHighlightDrawable(); 498622142ce9d8c6359d27b44827551c665c800347cJim Miller if (highlight != null) { 499622142ce9d8c6359d27b44827551c665c800347cJim Miller final View view = fpref.getView(); 500622142ce9d8c6359d27b44827551c665c800347cJim Miller final int centerX = view.getWidth() / 2; 501622142ce9d8c6359d27b44827551c665c800347cJim Miller final int centerY = view.getHeight() / 2; 502622142ce9d8c6359d27b44827551c665c800347cJim Miller highlight.setHotspot(centerX, centerY); 503622142ce9d8c6359d27b44827551c665c800347cJim Miller view.setBackground(highlight); 504622142ce9d8c6359d27b44827551c665c800347cJim Miller view.setPressed(true); 5051e2433693adbe2cca0feab79c18ae5be9e43d167Jorim Jaggi view.setPressed(false); 506622142ce9d8c6359d27b44827551c665c800347cJim Miller mHandler.postDelayed(new Runnable() { 507622142ce9d8c6359d27b44827551c665c800347cJim Miller @Override 508622142ce9d8c6359d27b44827551c665c800347cJim Miller public void run() { 509622142ce9d8c6359d27b44827551c665c800347cJim Miller view.setBackground(null); 510622142ce9d8c6359d27b44827551c665c800347cJim Miller } 511622142ce9d8c6359d27b44827551c665c800347cJim Miller }, RESET_HIGHLIGHT_DELAY_MS); 512622142ce9d8c6359d27b44827551c665c800347cJim Miller } 513a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller } 514a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller 515e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales private void launchChooseOrConfirmLock() { 516e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales Intent intent = new Intent(); 517e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales long challenge = mFingerprintManager.preEnroll(); 518e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales ChooseLockSettingsHelper helper = new ChooseLockSettingsHelper(getActivity(), this); 5195ad75f07b1861b802b75c720830db260b4f93417Jorim Jaggi if (!helper.launchConfirmationActivity(CONFIRM_REQUEST, 5205ad75f07b1861b802b75c720830db260b4f93417Jorim Jaggi getString(R.string.security_settings_fingerprint_preference_title), 5215ad75f07b1861b802b75c720830db260b4f93417Jorim Jaggi null, null, challenge)) { 522e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales intent.setClassName("com.android.settings", ChooseLockGeneric.class.getName()); 523e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.MINIMUM_QUALITY_KEY, 524e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales DevicePolicyManager.PASSWORD_QUALITY_SOMETHING); 525a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller intent.putExtra(ChooseLockGeneric.ChooseLockGenericFragment.HIDE_DISABLED_PREFS, 526a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller true); 527e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, true); 528e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, challenge); 529e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales startActivityForResult(intent, CHOOSE_LOCK_GENERIC_REQUEST); 530e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales } 531e29dae683e8334c18d1449fca3b0e27bc5ff7aaaAndres Morales } 532f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek 533f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek private void deleteFingerPrint(Fingerprint fingerPrint) { 534f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek mFingerprintManager.remove(fingerPrint, mRemoveCallback); 535f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek } 536f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek 537f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek private void renameFingerPrint(int fingerId, String newName) { 538f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek mFingerprintManager.rename(fingerId, newName); 539f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek updatePreferences(); 540f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek } 541f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek 5428e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller private final Runnable mFingerprintLockoutReset = new Runnable() { 5438e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller @Override 5448e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller public void run() { 5458e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller mInFingerprintLockout = false; 5468e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller retryFingerprint(); 5478e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller } 5488e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller }; 5498e8347502404dfed7d8f322eb033fa8645b8d753Jim Miller 550f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek public static class RenameDeleteDialog extends DialogFragment { 551f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek 552f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek private Fingerprint mFp; 553f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek private EditText mDialogTextField; 554f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek private String mFingerName; 555f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek private Boolean mTextHadFocus; 556f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek private int mTextSelectionStart; 557f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek private int mTextSelectionEnd; 558f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek 559f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek @Override 560f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek public Dialog onCreateDialog(Bundle savedInstanceState) { 561f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek mFp = getArguments().getParcelable("fingerprint"); 562f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek if (savedInstanceState != null) { 563f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek mFingerName = savedInstanceState.getString("fingerName"); 564f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek mTextHadFocus = savedInstanceState.getBoolean("textHadFocus"); 565f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek mTextSelectionStart = savedInstanceState.getInt("startSelection"); 566f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek mTextSelectionEnd = savedInstanceState.getInt("endSelection"); 567f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek } 568f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek final AlertDialog alertDialog = new AlertDialog.Builder(getActivity()) 569f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek .setView(R.layout.fingerprint_rename_dialog) 570f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek .setPositiveButton(R.string.security_settings_fingerprint_enroll_dialog_ok, 571f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek new DialogInterface.OnClickListener() { 572f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek @Override 573f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek public void onClick(DialogInterface dialog, int which) { 574f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek final String newName = 575f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek mDialogTextField.getText().toString(); 576f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek final CharSequence name = mFp.getName(); 577f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek if (!newName.equals(name)) { 578f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek if (DEBUG) { 579f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek Log.v(TAG, "rename " + name + " to " + newName); 580f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek } 5818c543276f1dd366bd142ce44a8e3084fddb22971Jorim Jaggi MetricsLogger.action(getContext(), 5821b8d5ffb47b674dd67ae6d56baa9ab3f42c8c024Chris Wren MetricsLogger.ACTION_FINGERPRINT_RENAME, 5831b8d5ffb47b674dd67ae6d56baa9ab3f42c8c024Chris Wren mFp.getFingerId()); 584f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek FingerprintSettingsFragment parent 585f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek = (FingerprintSettingsFragment) 586f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek getTargetFragment(); 587f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek parent.renameFingerPrint(mFp.getFingerId(), 588f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek newName); 589f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek } 590f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek dialog.dismiss(); 591f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek } 592f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek }) 593f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek .setNegativeButton( 594f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek R.string.security_settings_fingerprint_enroll_dialog_delete, 595f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek new DialogInterface.OnClickListener() { 596f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek @Override 597f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek public void onClick(DialogInterface dialog, int which) { 59812ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi onDeleteClick(dialog); 599f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek } 600f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek }) 601f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek .create(); 602f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek alertDialog.setOnShowListener(new DialogInterface.OnShowListener() { 603f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek @Override 604f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek public void onShow(DialogInterface dialog) { 605f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek mDialogTextField = (EditText) alertDialog.findViewById( 606f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek R.id.fingerprint_rename_field); 607f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek CharSequence name = mFingerName == null ? mFp.getName() : mFingerName; 608f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek mDialogTextField.setText(name); 609f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek if (mTextHadFocus == null) { 610f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek mDialogTextField.selectAll(); 611f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek } else { 612f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek mDialogTextField.setSelection(mTextSelectionStart, mTextSelectionEnd); 613f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek } 614f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek } 615f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek }); 616f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek if (mTextHadFocus == null || mTextHadFocus) { 617f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek // Request the IME 618f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek alertDialog.getWindow().setSoftInputMode( 619f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); 620f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek } 621f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek return alertDialog; 622f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek } 623f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek 62412ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi private void onDeleteClick(DialogInterface dialog) { 62512ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi if (DEBUG) Log.v(TAG, "Removing fpId=" + mFp.getFingerId()); 6268c543276f1dd366bd142ce44a8e3084fddb22971Jorim Jaggi MetricsLogger.action(getContext(), MetricsLogger.ACTION_FINGERPRINT_DELETE, 6271b8d5ffb47b674dd67ae6d56baa9ab3f42c8c024Chris Wren mFp.getFingerId()); 62812ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi FingerprintSettingsFragment parent 62912ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi = (FingerprintSettingsFragment) getTargetFragment(); 63012ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi if (parent.mFingerprintManager.getEnrolledFingerprints().size() > 1) { 63112ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi parent.deleteFingerPrint(mFp); 63212ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi } else { 63312ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi ConfirmLastDeleteDialog lastDeleteDialog = new ConfirmLastDeleteDialog(); 63412ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi Bundle args = new Bundle(); 63512ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi args.putParcelable("fingerprint", mFp); 63612ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi lastDeleteDialog.setArguments(args); 63712ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi lastDeleteDialog.setTargetFragment(getTargetFragment(), 0); 63812ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi lastDeleteDialog.show(getFragmentManager(), 63912ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi ConfirmLastDeleteDialog.class.getName()); 64012ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi } 64112ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi dialog.dismiss(); 64212ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi } 64312ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi 644f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek @Override 645f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek public void onSaveInstanceState(Bundle outState) { 646f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek super.onSaveInstanceState(outState); 647f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek if (mDialogTextField != null) { 648f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek outState.putString("fingerName", mDialogTextField.getText().toString()); 649f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek outState.putBoolean("textHadFocus", mDialogTextField.hasFocus()); 650f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek outState.putInt("startSelection", mDialogTextField.getSelectionStart()); 651f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek outState.putInt("endSelection", mDialogTextField.getSelectionEnd()); 652f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek } 653f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek } 654f4a305ee407082bdb6e47cefbb5682e46df49794Selim Cinek } 65512ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi 65612ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi public static class ConfirmLastDeleteDialog extends DialogFragment { 65712ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi 65812ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi private Fingerprint mFp; 65912ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi 66012ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi @Override 66112ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi public Dialog onCreateDialog(Bundle savedInstanceState) { 66212ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi mFp = getArguments().getParcelable("fingerprint"); 66312ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi final AlertDialog alertDialog = new AlertDialog.Builder(getActivity()) 66412ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi .setTitle(R.string.fingerprint_last_delete_title) 66512ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi .setMessage(R.string.fingerprint_last_delete_message) 66612ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi .setPositiveButton(R.string.fingerprint_last_delete_confirm, 66712ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi new DialogInterface.OnClickListener() { 66812ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi @Override 66912ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi public void onClick(DialogInterface dialog, int which) { 67012ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi FingerprintSettingsFragment parent 67112ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi = (FingerprintSettingsFragment) getTargetFragment(); 67212ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi parent.deleteFingerPrint(mFp); 67312ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi dialog.dismiss(); 67412ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi } 67512ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi }) 67612ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi .setNegativeButton( 67712ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi R.string.cancel, 67812ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi new DialogInterface.OnClickListener() { 67912ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi @Override 68012ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi public void onClick(DialogInterface dialog, int which) { 68112ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi dialog.dismiss(); 68212ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi } 68312ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi }) 68412ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi .create(); 68512ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi return alertDialog; 68612ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi } 68712ee807c1fbef73d9a05cff523d797748d209002Jorim Jaggi } 6889218687e4baaf0226ef16b58f78123d979711e5dJim Miller } 6894f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller 6904f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller public static class FingerprintPreference extends Preference { 691d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller private Fingerprint mFingerprint; 6924f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller private View mView; 6934f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller 6944f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller public FingerprintPreference(Context context, AttributeSet attrs, int defStyleAttr, 6954f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller int defStyleRes) { 6964f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller super(context, attrs, defStyleAttr, defStyleRes); 6974f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller } 6984f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller public FingerprintPreference(Context context, AttributeSet attrs, int defStyleAttr) { 6994f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller this(context, attrs, defStyleAttr, 0); 7004f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller } 7014f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller 7024f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller public FingerprintPreference(Context context, AttributeSet attrs) { 7034f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller this(context, attrs, com.android.internal.R.attr.preferenceStyle); 7044f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller } 7054f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller 7064f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller public FingerprintPreference(Context context) { 7074f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller this(context, null); 7084f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller } 7094f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller 710a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller public View getView() { return mView; } 711a8e22985d7866fb0528d85d9710a5bc0f482d91aJim Miller 712d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller public void setFingerprint(Fingerprint item) { 713d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller mFingerprint = item; 7144f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller } 7154f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller 716d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller public Fingerprint getFingerprint() { 717d16c9b7c3100b7ba653dcd58db036500dd220896Jim Miller return mFingerprint; 7184f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller } 7194f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller 7204f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller @Override 7214f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller protected void onBindView(View view) { 7224f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller super.onBindView(view); 7234f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller mView = view; 7244f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller } 7254f6f7c865f25f478e5198031d419b498bdeb7ffaJim Miller }; 7264dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi 7274dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi private static class LearnMoreSpan extends URLSpan { 7284dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi 7294dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi private static final Typeface TYPEFACE_MEDIUM = 7304dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi Typeface.create("sans-serif-medium", Typeface.NORMAL); 7314dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi 7324dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi private LearnMoreSpan(String url) { 7334dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi super(url); 7344dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi } 7354dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi 7364dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi @Override 7374dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi public void onClick(View widget) { 7384dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi Context ctx = widget.getContext(); 73915dcebe1e79ad396a08873f940e2f33d432cf387Jason Monk Intent intent = HelpUtils.getHelpIntent(ctx, getURL(), ctx.getClass().getName()); 7404dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi try { 7416e61347242ea8d9ac0645b2669f222696c65eec6Jason Monk ((Activity) ctx).startActivityForResult(intent, 0); 7424dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi } catch (ActivityNotFoundException e) { 7434dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi Log.w(FingerprintSettingsFragment.TAG, 7444dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi "Actvity was not found for intent, " + intent.toString()); 7454dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi } 7464dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi } 7474dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi 7484dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi @Override 7494dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi public void updateDrawState(TextPaint ds) { 7504dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi super.updateDrawState(ds); 7514dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi ds.setUnderlineText(false); 7524dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi ds.setTypeface(TYPEFACE_MEDIUM); 7534dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi } 7544dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi 7554dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi public static CharSequence linkify(CharSequence rawText, String uri) { 7564dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi SpannableString msg = new SpannableString(rawText); 7574dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi Annotation[] spans = msg.getSpans(0, msg.length(), Annotation.class); 7584dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi SpannableStringBuilder builder = new SpannableStringBuilder(msg); 7594dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi for (Annotation annotation : spans) { 7604dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi int start = msg.getSpanStart(annotation); 7614dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi int end = msg.getSpanEnd(annotation); 7624dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi LearnMoreSpan link = new LearnMoreSpan(uri); 7634dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi builder.setSpan(link, start, end, msg.getSpanFlags(link)); 7644dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi } 7654dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi return builder; 7664dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi } 7674dfcb8208cdb49167ccf99aeaddf9e206eba87d1Jorim Jaggi } 7689218687e4baaf0226ef16b58f78123d979711e5dJim Miller} 769