Home | History | Annotate | Download | only in settings
      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