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