ChooseLockGeneric.java revision fe432e838e5588cd4ac664d7e74f3d70a99d7df1
1/* 2 * Copyright (C) 2010 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.settings; 18 19import android.accessibilityservice.AccessibilityServiceInfo; 20import android.app.Activity; 21import android.app.AlertDialog; 22import android.app.Dialog; 23import android.app.DialogFragment; 24import android.app.Fragment; 25import android.app.FragmentManager; 26import android.app.admin.DevicePolicyManager; 27import android.content.Context; 28import android.content.DialogInterface; 29import android.content.Intent; 30import android.hardware.fingerprint.Fingerprint; 31import android.hardware.fingerprint.FingerprintManager; 32import android.hardware.fingerprint.FingerprintManager.RemovalCallback; 33import android.os.Bundle; 34import android.os.Process; 35import android.os.UserHandle; 36import android.security.KeyStore; 37import android.support.v7.preference.Preference; 38import android.support.v7.preference.PreferenceScreen; 39import android.util.EventLog; 40import android.util.Log; 41import android.view.View; 42import android.view.accessibility.AccessibilityManager; 43import android.widget.Toast; 44 45import com.android.internal.logging.MetricsLogger; 46import com.android.internal.widget.LockPatternUtils; 47 48public class ChooseLockGeneric extends SettingsActivity { 49 public static final String CONFIRM_CREDENTIALS = "confirm_credentials"; 50 public static final String KEY_USER_ID = "user_id"; 51 52 @Override 53 public Intent getIntent() { 54 Intent modIntent = new Intent(super.getIntent()); 55 modIntent.putExtra(EXTRA_SHOW_FRAGMENT, getFragmentClass().getName()); 56 return modIntent; 57 } 58 59 @Override 60 protected boolean isValidFragment(String fragmentName) { 61 if (ChooseLockGenericFragment.class.getName().equals(fragmentName)) return true; 62 return false; 63 } 64 65 /* package */ Class<? extends Fragment> getFragmentClass() { 66 return ChooseLockGenericFragment.class; 67 } 68 69 public static class InternalActivity extends ChooseLockGeneric { 70 } 71 72 public static class ChooseLockGenericFragment extends SettingsPreferenceFragment { 73 private static final String TAG = "ChooseLockGenericFragment"; 74 private static final int MIN_PASSWORD_LENGTH = 4; 75 private static final String KEY_UNLOCK_SET_OFF = "unlock_set_off"; 76 private static final String KEY_UNLOCK_SET_NONE = "unlock_set_none"; 77 private static final String KEY_UNLOCK_SET_PIN = "unlock_set_pin"; 78 private static final String KEY_UNLOCK_SET_PASSWORD = "unlock_set_password"; 79 private static final String KEY_UNLOCK_SET_PATTERN = "unlock_set_pattern"; 80 private static final String PASSWORD_CONFIRMED = "password_confirmed"; 81 private static final String WAITING_FOR_CONFIRMATION = "waiting_for_confirmation"; 82 public static final String MINIMUM_QUALITY_KEY = "minimum_quality"; 83 public static final String HIDE_DISABLED_PREFS = "hide_disabled_prefs"; 84 public static final String ENCRYPT_REQUESTED_QUALITY = "encrypt_requested_quality"; 85 public static final String ENCRYPT_REQUESTED_DISABLED = "encrypt_requested_disabled"; 86 public static final String TAG_FRP_WARNING_DIALOG = "frp_warning_dialog"; 87 88 private static final int CONFIRM_EXISTING_REQUEST = 100; 89 private static final int ENABLE_ENCRYPTION_REQUEST = 101; 90 private static final int CHOOSE_LOCK_REQUEST = 102; 91 92 private ChooseLockSettingsHelper mChooseLockSettingsHelper; 93 private DevicePolicyManager mDPM; 94 private KeyStore mKeyStore; 95 private boolean mHasChallenge = false; 96 private long mChallenge; 97 private boolean mPasswordConfirmed = false; 98 private boolean mWaitingForConfirmation = false; 99 private int mEncryptionRequestQuality; 100 private boolean mEncryptionRequestDisabled; 101 private boolean mRequirePassword; 102 private boolean mForFingerprint = false; 103 private String mUserPassword; 104 private LockPatternUtils mLockPatternUtils; 105 private FingerprintManager mFingerprintManager; 106 private int mUserId; 107 private RemovalCallback mRemovalCallback = new RemovalCallback() { 108 109 @Override 110 public void onRemovalSucceeded(Fingerprint fingerprint) { 111 Log.v(TAG, "Fingerprint removed: " + fingerprint.getFingerId()); 112 if (mFingerprintManager.getEnrolledFingerprints().size() == 0) { 113 finish(); 114 } 115 } 116 117 @Override 118 public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString) { 119 Activity activity = getActivity(); 120 if (activity != null) { 121 Toast.makeText(getActivity(), errString, Toast.LENGTH_SHORT); 122 } 123 finish(); 124 } 125 }; 126 127 @Override 128 protected int getMetricsCategory() { 129 return MetricsLogger.CHOOSE_LOCK_GENERIC; 130 } 131 132 @Override 133 public void onCreate(Bundle savedInstanceState) { 134 super.onCreate(savedInstanceState); 135 136 mFingerprintManager = 137 (FingerprintManager) getActivity().getSystemService(Context.FINGERPRINT_SERVICE); 138 mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); 139 mKeyStore = KeyStore.getInstance(); 140 mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this.getActivity()); 141 mLockPatternUtils = new LockPatternUtils(getActivity()); 142 143 // Defaults to needing to confirm credentials 144 final boolean confirmCredentials = getActivity().getIntent() 145 .getBooleanExtra(CONFIRM_CREDENTIALS, true); 146 if (getActivity() instanceof ChooseLockGeneric.InternalActivity) { 147 mPasswordConfirmed = !confirmCredentials; 148 } 149 150 mHasChallenge = getActivity().getIntent().getBooleanExtra( 151 ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false); 152 mChallenge = getActivity().getIntent().getLongExtra( 153 ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0); 154 mForFingerprint = getActivity().getIntent().getBooleanExtra( 155 ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false); 156 157 if (savedInstanceState != null) { 158 mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED); 159 mWaitingForConfirmation = savedInstanceState.getBoolean(WAITING_FOR_CONFIRMATION); 160 mEncryptionRequestQuality = savedInstanceState.getInt(ENCRYPT_REQUESTED_QUALITY); 161 mEncryptionRequestDisabled = savedInstanceState.getBoolean( 162 ENCRYPT_REQUESTED_DISABLED); 163 } 164 165 // Only take this argument into account if it belongs to the current profile. 166 mUserId = Utils.getSameOwnerUserId(getContext(), getArguments()); 167 168 if (mPasswordConfirmed) { 169 updatePreferencesOrFinish(); 170 } else if (!mWaitingForConfirmation) { 171 ChooseLockSettingsHelper helper = 172 new ChooseLockSettingsHelper(this.getActivity(), this); 173 if (!helper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST, 174 getString(R.string.unlock_set_unlock_launch_picker_title), true, mUserId)) { 175 mPasswordConfirmed = true; // no password set, so no need to confirm 176 updatePreferencesOrFinish(); 177 } else { 178 mWaitingForConfirmation = true; 179 } 180 } 181 } 182 183 @Override 184 public void onViewCreated(View view, Bundle savedInstanceState) { 185 super.onViewCreated(view, savedInstanceState); 186 if (mForFingerprint) { 187 setHeaderView(R.layout.choose_lock_generic_fingerprint_header); 188 } 189 } 190 191 @Override 192 public boolean onPreferenceTreeClick(Preference preference) { 193 final String key = preference.getKey(); 194 195 if (!isUnlockMethodSecure(key) && mLockPatternUtils.isSecure(mUserId)) { 196 // Show the disabling FRP warning only when the user is switching from a secure 197 // unlock method to an insecure one 198 showFactoryResetProtectionWarningDialog(key); 199 return true; 200 } else { 201 return setUnlockMethod(key); 202 } 203 } 204 205 /** 206 * If the device has encryption already enabled, then ask the user if they 207 * also want to encrypt the phone with this password. 208 * 209 * @param quality 210 * @param disabled 211 */ 212 // TODO: why does this take disabled, its always called with a quality higher than 213 // what makes sense with disabled == true 214 private void maybeEnableEncryption(int quality, boolean disabled) { 215 DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE); 216 if (Process.myUserHandle().isOwner() && LockPatternUtils.isDeviceEncryptionEnabled() 217 && !dpm.getDoNotAskCredentialsOnBoot()) { 218 mEncryptionRequestQuality = quality; 219 mEncryptionRequestDisabled = disabled; 220 final Context context = getActivity(); 221 // If accessibility is enabled and the user hasn't seen this dialog before, set the 222 // default state to agree with that which is compatible with accessibility 223 // (password not required). 224 final boolean accEn = AccessibilityManager.getInstance(context).isEnabled(); 225 final boolean required = mLockPatternUtils.isCredentialRequiredToDecrypt(!accEn); 226 Intent intent = getEncryptionInterstitialIntent(context, quality, required); 227 intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, 228 mForFingerprint); 229 startActivityForResult(intent, ENABLE_ENCRYPTION_REQUEST); 230 } else { 231 mRequirePassword = false; // device encryption not enabled or not device owner. 232 updateUnlockMethodAndFinish(quality, disabled); 233 } 234 } 235 236 @Override 237 public void onActivityResult(int requestCode, int resultCode, Intent data) { 238 super.onActivityResult(requestCode, resultCode, data); 239 mWaitingForConfirmation = false; 240 if (requestCode == CONFIRM_EXISTING_REQUEST && resultCode == Activity.RESULT_OK) { 241 mPasswordConfirmed = true; 242 mUserPassword = data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD); 243 updatePreferencesOrFinish(); 244 } else if (requestCode == ENABLE_ENCRYPTION_REQUEST 245 && resultCode == Activity.RESULT_OK) { 246 mRequirePassword = data.getBooleanExtra( 247 EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true); 248 updateUnlockMethodAndFinish(mEncryptionRequestQuality, mEncryptionRequestDisabled); 249 } else if (requestCode == CHOOSE_LOCK_REQUEST) { 250 getActivity().setResult(resultCode, data); 251 finish(); 252 } else { 253 getActivity().setResult(Activity.RESULT_CANCELED); 254 finish(); 255 } 256 } 257 258 @Override 259 public void onSaveInstanceState(Bundle outState) { 260 super.onSaveInstanceState(outState); 261 // Saved so we don't force user to re-enter their password if configuration changes 262 outState.putBoolean(PASSWORD_CONFIRMED, mPasswordConfirmed); 263 outState.putBoolean(WAITING_FOR_CONFIRMATION, mWaitingForConfirmation); 264 outState.putInt(ENCRYPT_REQUESTED_QUALITY, mEncryptionRequestQuality); 265 outState.putBoolean(ENCRYPT_REQUESTED_DISABLED, mEncryptionRequestDisabled); 266 } 267 268 private void updatePreferencesOrFinish() { 269 Intent intent = getActivity().getIntent(); 270 int quality = intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, -1); 271 if (quality == -1) { 272 // If caller didn't specify password quality, show UI and allow the user to choose. 273 quality = intent.getIntExtra(MINIMUM_QUALITY_KEY, -1); 274 quality = upgradeQuality(quality); 275 final boolean hideDisabledPrefs = intent.getBooleanExtra( 276 HIDE_DISABLED_PREFS, false); 277 final PreferenceScreen prefScreen = getPreferenceScreen(); 278 if (prefScreen != null) { 279 prefScreen.removeAll(); 280 } 281 addPreferencesFromResource(R.xml.security_settings_picker); 282 disableUnusablePreferences(quality, hideDisabledPrefs); 283 updateCurrentPreference(); 284 updatePreferenceSummaryIfNeeded(); 285 } else { 286 updateUnlockMethodAndFinish(quality, false); 287 } 288 } 289 290 private void updateCurrentPreference() { 291 String currentKey = getKeyForCurrent(); 292 Preference preference = findPreference(currentKey); 293 if (preference != null) { 294 preference.setSummary(R.string.current_screen_lock); 295 } 296 } 297 298 private String getKeyForCurrent() { 299 if (mLockPatternUtils.isLockScreenDisabled(mUserId)) { 300 return KEY_UNLOCK_SET_OFF; 301 } 302 switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId)) { 303 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: 304 return KEY_UNLOCK_SET_PATTERN; 305 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: 306 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX: 307 return KEY_UNLOCK_SET_PIN; 308 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC: 309 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC: 310 return KEY_UNLOCK_SET_PASSWORD; 311 case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED: 312 return KEY_UNLOCK_SET_NONE; 313 } 314 return null; 315 } 316 317 /** increases the quality if necessary */ 318 private int upgradeQuality(int quality) { 319 quality = upgradeQualityForDPM(quality); 320 return quality; 321 } 322 323 private int upgradeQualityForDPM(int quality) { 324 // Compare min allowed password quality 325 int minQuality = mDPM.getPasswordQuality(null); 326 if (quality < minQuality) { 327 quality = minQuality; 328 } 329 return quality; 330 } 331 332 /*** 333 * Disables preferences that are less secure than required quality. The actual 334 * implementation is in disableUnusablePreferenceImpl. 335 * 336 * @param quality the requested quality. 337 * @param hideDisabledPrefs if false preferences show why they were disabled; otherwise 338 * they're not shown at all. 339 */ 340 protected void disableUnusablePreferences(final int quality, boolean hideDisabledPrefs) { 341 disableUnusablePreferencesImpl(quality, hideDisabledPrefs); 342 } 343 344 /*** 345 * Disables preferences that are less secure than required quality. 346 * 347 * @param quality the requested quality. 348 * @param hideDisabled whether to hide disable screen lock options. 349 */ 350 protected void disableUnusablePreferencesImpl(final int quality, 351 boolean hideDisabled) { 352 final PreferenceScreen entries = getPreferenceScreen(); 353 354 for (int i = entries.getPreferenceCount() - 1; i >= 0; --i) { 355 Preference pref = entries.getPreference(i); 356 if (pref instanceof PreferenceScreen) { 357 final String key = pref.getKey(); 358 boolean enabled = true; 359 boolean visible = true; 360 if (KEY_UNLOCK_SET_OFF.equals(key)) { 361 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 362 if (getResources().getBoolean(R.bool.config_hide_none_security_option)) { 363 enabled = false; 364 visible = false; 365 } 366 } else if (KEY_UNLOCK_SET_NONE.equals(key)) { 367 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; 368 } else if (KEY_UNLOCK_SET_PATTERN.equals(key)) { 369 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; 370 } else if (KEY_UNLOCK_SET_PIN.equals(key)) { 371 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX; 372 } else if (KEY_UNLOCK_SET_PASSWORD.equals(key)) { 373 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_COMPLEX; 374 } 375 if (hideDisabled) { 376 visible = enabled; 377 } 378 if (!visible) { 379 entries.removePreference(pref); 380 } else if (!enabled) { 381 pref.setSummary(R.string.unlock_set_unlock_disabled_summary); 382 pref.setEnabled(false); 383 } 384 } 385 } 386 } 387 388 private void updatePreferenceSummaryIfNeeded() { 389 if (LockPatternUtils.isDeviceEncrypted()) { 390 return; 391 } 392 393 if (AccessibilityManager.getInstance(getActivity()).getEnabledAccessibilityServiceList( 394 AccessibilityServiceInfo.FEEDBACK_ALL_MASK).isEmpty()) { 395 return; 396 } 397 398 CharSequence summary = getString(R.string.secure_lock_encryption_warning); 399 400 PreferenceScreen screen = getPreferenceScreen(); 401 final int preferenceCount = screen.getPreferenceCount(); 402 for (int i = 0; i < preferenceCount; i++) { 403 Preference preference = screen.getPreference(i); 404 switch (preference.getKey()) { 405 case KEY_UNLOCK_SET_PATTERN: 406 case KEY_UNLOCK_SET_PIN: 407 case KEY_UNLOCK_SET_PASSWORD: { 408 preference.setSummary(summary); 409 } break; 410 } 411 } 412 } 413 414 protected Intent getLockPasswordIntent(Context context, int quality, 415 int minLength, final int maxLength, 416 boolean requirePasswordToDecrypt, boolean confirmCredentials, int userId) { 417 return ChooseLockPassword.createIntent(context, quality, minLength, 418 maxLength, requirePasswordToDecrypt, confirmCredentials, userId); 419 } 420 421 protected Intent getLockPasswordIntent(Context context, int quality, 422 int minLength, final int maxLength, 423 boolean requirePasswordToDecrypt, long challenge, int userId) { 424 return ChooseLockPassword.createIntent(context, quality, minLength, 425 maxLength, requirePasswordToDecrypt, challenge, userId); 426 } 427 428 protected Intent getLockPasswordIntent(Context context, int quality, int minLength, 429 int maxLength, boolean requirePasswordToDecrypt, String password, int userId) { 430 return ChooseLockPassword.createIntent(context, quality, minLength, maxLength, 431 requirePasswordToDecrypt, password, userId); 432 } 433 434 protected Intent getLockPatternIntent(Context context, final boolean requirePassword, 435 final boolean confirmCredentials, int userId) { 436 return ChooseLockPattern.createIntent(context, requirePassword, 437 confirmCredentials, userId); 438 } 439 440 protected Intent getLockPatternIntent(Context context, final boolean requirePassword, 441 long challenge, int userId) { 442 return ChooseLockPattern.createIntent(context, requirePassword, challenge, userId); 443 } 444 445 protected Intent getLockPatternIntent(Context context, final boolean requirePassword, 446 final String pattern, int userId) { 447 return ChooseLockPattern.createIntent(context, requirePassword, pattern, userId); 448 } 449 450 protected Intent getEncryptionInterstitialIntent(Context context, int quality, 451 boolean required) { 452 return EncryptionInterstitial.createStartIntent(context, quality, required); 453 } 454 455 /** 456 * Invokes an activity to change the user's pattern, password or PIN based on given quality 457 * and minimum quality specified by DevicePolicyManager. If quality is 458 * {@link DevicePolicyManager#PASSWORD_QUALITY_UNSPECIFIED}, password is cleared. 459 * 460 * @param quality the desired quality. Ignored if DevicePolicyManager requires more security 461 * @param disabled whether or not to show LockScreen at all. Only meaningful when quality is 462 * {@link DevicePolicyManager#PASSWORD_QUALITY_UNSPECIFIED} 463 */ 464 void updateUnlockMethodAndFinish(int quality, boolean disabled) { 465 // Sanity check. We should never get here without confirming user's existing password. 466 if (!mPasswordConfirmed) { 467 throw new IllegalStateException("Tried to update password without confirming it"); 468 } 469 470 quality = upgradeQuality(quality); 471 472 final Context context = getActivity(); 473 if (quality >= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) { 474 int minLength = mDPM.getPasswordMinimumLength(null); 475 if (minLength < MIN_PASSWORD_LENGTH) { 476 minLength = MIN_PASSWORD_LENGTH; 477 } 478 final int maxLength = mDPM.getPasswordMaximumLength(quality); 479 Intent intent; 480 if (mHasChallenge) { 481 intent = getLockPasswordIntent(context, quality, minLength, 482 maxLength, mRequirePassword, mChallenge, mUserId); 483 } else { 484 intent = getLockPasswordIntent(context, quality, minLength, 485 maxLength, mRequirePassword, mUserPassword, mUserId); 486 } 487 startActivityForResult(intent, CHOOSE_LOCK_REQUEST); 488 } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) { 489 Intent intent; 490 if (mHasChallenge) { 491 intent = getLockPatternIntent(context, mRequirePassword, 492 mChallenge, mUserId); 493 } else { 494 intent = getLockPatternIntent(context, mRequirePassword, 495 mUserPassword, mUserId); 496 } 497 startActivityForResult(intent, CHOOSE_LOCK_REQUEST); 498 } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) { 499 mChooseLockSettingsHelper.utils().clearLock(mUserId); 500 mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled, mUserId); 501 removeAllFingerprintTemplatesAndFinish(); 502 getActivity().setResult(Activity.RESULT_OK); 503 } else { 504 removeAllFingerprintTemplatesAndFinish(); 505 } 506 } 507 508 private void removeAllFingerprintTemplatesAndFinish() { 509 if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected() 510 && mFingerprintManager.getEnrolledFingerprints().size() > 0) { 511 mFingerprintManager.remove(new Fingerprint(null, 0, 0, 0), mRemovalCallback); 512 } else { 513 finish(); 514 } 515 } 516 517 @Override 518 public void onDestroy() { 519 super.onDestroy(); 520 } 521 522 @Override 523 protected int getHelpResource() { 524 return R.string.help_url_choose_lockscreen; 525 } 526 527 private int getResIdForFactoryResetProtectionWarningMessage() { 528 boolean hasFingerprints = mFingerprintManager.hasEnrolledFingerprints(); 529 switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId)) { 530 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: 531 return hasFingerprints 532 ? R.string.unlock_disable_frp_warning_content_pattern_fingerprint 533 : R.string.unlock_disable_frp_warning_content_pattern; 534 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: 535 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX: 536 return hasFingerprints 537 ? R.string.unlock_disable_frp_warning_content_pin_fingerprint 538 : R.string.unlock_disable_frp_warning_content_pin; 539 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC: 540 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC: 541 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX: 542 return hasFingerprints 543 ? R.string.unlock_disable_frp_warning_content_password_fingerprint 544 : R.string.unlock_disable_frp_warning_content_password; 545 default: 546 return hasFingerprints 547 ? R.string.unlock_disable_frp_warning_content_unknown_fingerprint 548 : R.string.unlock_disable_frp_warning_content_unknown; 549 } 550 } 551 552 private boolean isUnlockMethodSecure(String unlockMethod) { 553 return !(KEY_UNLOCK_SET_OFF.equals(unlockMethod) || 554 KEY_UNLOCK_SET_NONE.equals(unlockMethod)); 555 } 556 557 private boolean setUnlockMethod(String unlockMethod) { 558 EventLog.writeEvent(EventLogTags.LOCK_SCREEN_TYPE, unlockMethod); 559 560 if (KEY_UNLOCK_SET_OFF.equals(unlockMethod)) { 561 updateUnlockMethodAndFinish( 562 DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, true /* disabled */ ); 563 } else if (KEY_UNLOCK_SET_NONE.equals(unlockMethod)) { 564 updateUnlockMethodAndFinish( 565 DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, false /* disabled */ ); 566 } else if (KEY_UNLOCK_SET_PATTERN.equals(unlockMethod)) { 567 maybeEnableEncryption( 568 DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, false); 569 } else if (KEY_UNLOCK_SET_PIN.equals(unlockMethod)) { 570 maybeEnableEncryption( 571 DevicePolicyManager.PASSWORD_QUALITY_NUMERIC, false); 572 } else if (KEY_UNLOCK_SET_PASSWORD.equals(unlockMethod)) { 573 maybeEnableEncryption( 574 DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC, false); 575 } else { 576 Log.e(TAG, "Encountered unknown unlock method to set: " + unlockMethod); 577 return false; 578 } 579 return true; 580 } 581 582 private void showFactoryResetProtectionWarningDialog(String unlockMethodToSet) { 583 int message = getResIdForFactoryResetProtectionWarningMessage(); 584 FactoryResetProtectionWarningDialog dialog = 585 FactoryResetProtectionWarningDialog.newInstance(message, unlockMethodToSet); 586 dialog.show(getChildFragmentManager(), TAG_FRP_WARNING_DIALOG); 587 } 588 589 public static class FactoryResetProtectionWarningDialog extends DialogFragment { 590 591 private static final String ARG_MESSAGE_RES = "messageRes"; 592 private static final String ARG_UNLOCK_METHOD_TO_SET = "unlockMethodToSet"; 593 594 public static FactoryResetProtectionWarningDialog newInstance(int messageRes, 595 String unlockMethodToSet) { 596 FactoryResetProtectionWarningDialog frag = 597 new FactoryResetProtectionWarningDialog(); 598 Bundle args = new Bundle(); 599 args.putInt(ARG_MESSAGE_RES, messageRes); 600 args.putString(ARG_UNLOCK_METHOD_TO_SET, unlockMethodToSet); 601 frag.setArguments(args); 602 return frag; 603 } 604 605 @Override 606 public void show(FragmentManager manager, String tag) { 607 if (manager.findFragmentByTag(tag) == null) { 608 // Prevent opening multiple dialogs if tapped on button quickly 609 super.show(manager, tag); 610 } 611 } 612 613 @Override 614 public Dialog onCreateDialog(Bundle savedInstanceState) { 615 final Bundle args = getArguments(); 616 617 return new AlertDialog.Builder(getActivity()) 618 .setTitle(R.string.unlock_disable_frp_warning_title) 619 .setMessage(args.getInt(ARG_MESSAGE_RES)) 620 .setPositiveButton(R.string.unlock_disable_frp_warning_ok, 621 new DialogInterface.OnClickListener() { 622 @Override 623 public void onClick(DialogInterface dialog, int whichButton) { 624 ((ChooseLockGenericFragment) getParentFragment()) 625 .setUnlockMethod( 626 args.getString(ARG_UNLOCK_METHOD_TO_SET)); 627 } 628 } 629 ) 630 .setNegativeButton(R.string.cancel, 631 new DialogInterface.OnClickListener() { 632 @Override 633 public void onClick(DialogInterface dialog, int whichButton) { 634 dismiss(); 635 } 636 } 637 ) 638 .create(); 639 } 640 } 641 } 642} 643