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