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.admin.DevicePolicyManager;
     27 import android.content.Context;
     28 import android.content.DialogInterface;
     29 import android.content.Intent;
     30 import android.content.pm.UserInfo;
     31 import android.hardware.fingerprint.Fingerprint;
     32 import android.hardware.fingerprint.FingerprintManager;
     33 import android.hardware.fingerprint.FingerprintManager.RemovalCallback;
     34 import android.os.Bundle;
     35 import android.os.UserHandle;
     36 import android.os.UserManager;
     37 import android.os.storage.StorageManager;
     38 import android.security.KeyStore;
     39 import android.support.v7.preference.Preference;
     40 import android.support.v7.preference.PreferenceScreen;
     41 import android.text.TextUtils;
     42 import android.util.EventLog;
     43 import android.util.Log;
     44 import android.view.accessibility.AccessibilityManager;
     45 
     46 import com.android.internal.logging.MetricsProto.MetricsEvent;
     47 import com.android.internal.widget.LockPatternUtils;
     48 import com.android.settingslib.RestrictedLockUtils;
     49 import com.android.settingslib.RestrictedPreference;
     50 
     51 import java.util.List;
     52 
     53 import static com.android.settingslib.RestrictedLockUtils.EnforcedAdmin;
     54 
     55 public class ChooseLockGeneric extends SettingsActivity {
     56     public static final String CONFIRM_CREDENTIALS = "confirm_credentials";
     57 
     58     @Override
     59     public Intent getIntent() {
     60         Intent modIntent = new Intent(super.getIntent());
     61         modIntent.putExtra(EXTRA_SHOW_FRAGMENT, getFragmentClass().getName());
     62 
     63         String action = modIntent.getAction();
     64         if (DevicePolicyManager.ACTION_SET_NEW_PASSWORD.equals(action)
     65                 || DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(action)) {
     66             modIntent.putExtra(EXTRA_HIDE_DRAWER, true);
     67         }
     68         return modIntent;
     69     }
     70 
     71     @Override
     72     protected boolean isValidFragment(String fragmentName) {
     73         if (ChooseLockGenericFragment.class.getName().equals(fragmentName)) return true;
     74         return false;
     75     }
     76 
     77     /* package */ Class<? extends Fragment> getFragmentClass() {
     78         return ChooseLockGenericFragment.class;
     79     }
     80 
     81     public static class InternalActivity extends ChooseLockGeneric {
     82     }
     83 
     84     public static class ChooseLockGenericFragment extends SettingsPreferenceFragment {
     85         private static final String TAG = "ChooseLockGenericFragment";
     86         private static final int MIN_PASSWORD_LENGTH = 4;
     87         private static final String KEY_UNLOCK_SET_OFF = "unlock_set_off";
     88         private static final String KEY_UNLOCK_SET_NONE = "unlock_set_none";
     89         private static final String KEY_UNLOCK_SET_PIN = "unlock_set_pin";
     90         private static final String KEY_UNLOCK_SET_PASSWORD = "unlock_set_password";
     91         private static final String KEY_UNLOCK_SET_PATTERN = "unlock_set_pattern";
     92         private static final String KEY_UNLOCK_SET_MANAGED = "unlock_set_managed";
     93         private static final String PASSWORD_CONFIRMED = "password_confirmed";
     94         private static final String WAITING_FOR_CONFIRMATION = "waiting_for_confirmation";
     95         public static final String MINIMUM_QUALITY_KEY = "minimum_quality";
     96         public static final String HIDE_DISABLED_PREFS = "hide_disabled_prefs";
     97         public static final String ENCRYPT_REQUESTED_QUALITY = "encrypt_requested_quality";
     98         public static final String ENCRYPT_REQUESTED_DISABLED = "encrypt_requested_disabled";
     99         public static final String TAG_FRP_WARNING_DIALOG = "frp_warning_dialog";
    100 
    101         private static final int CONFIRM_EXISTING_REQUEST = 100;
    102         private static final int ENABLE_ENCRYPTION_REQUEST = 101;
    103         private static final int CHOOSE_LOCK_REQUEST = 102;
    104 
    105         private ChooseLockSettingsHelper mChooseLockSettingsHelper;
    106         private DevicePolicyManager mDPM;
    107         private KeyStore mKeyStore;
    108         private boolean mHasChallenge = false;
    109         private long mChallenge;
    110         private boolean mPasswordConfirmed = false;
    111         private boolean mWaitingForConfirmation = false;
    112         private int mEncryptionRequestQuality;
    113         private boolean mEncryptionRequestDisabled;
    114         private boolean mRequirePassword;
    115         private boolean mForChangeCredRequiredForBoot = false;
    116         private String mUserPassword;
    117         private LockPatternUtils mLockPatternUtils;
    118         private FingerprintManager mFingerprintManager;
    119         private int mUserId;
    120         private boolean mHideDrawer = false;
    121         private ManagedLockPasswordProvider mManagedPasswordProvider;
    122 
    123         protected boolean mForFingerprint = false;
    124 
    125         @Override
    126         protected int getMetricsCategory() {
    127             return MetricsEvent.CHOOSE_LOCK_GENERIC;
    128         }
    129 
    130         @Override
    131         public void onCreate(Bundle savedInstanceState) {
    132             super.onCreate(savedInstanceState);
    133 
    134             mFingerprintManager =
    135                 (FingerprintManager) getActivity().getSystemService(Context.FINGERPRINT_SERVICE);
    136             mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
    137             mKeyStore = KeyStore.getInstance();
    138             mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this.getActivity());
    139             mLockPatternUtils = new LockPatternUtils(getActivity());
    140 
    141             // Defaults to needing to confirm credentials
    142             final boolean confirmCredentials = getActivity().getIntent()
    143                 .getBooleanExtra(CONFIRM_CREDENTIALS, true);
    144             if (getActivity() instanceof ChooseLockGeneric.InternalActivity) {
    145                 mPasswordConfirmed = !confirmCredentials;
    146             }
    147             mHideDrawer = getActivity().getIntent().getBooleanExtra(EXTRA_HIDE_DRAWER, false);
    148 
    149             mHasChallenge = getActivity().getIntent().getBooleanExtra(
    150                     ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
    151             mChallenge = getActivity().getIntent().getLongExtra(
    152                     ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
    153             mForFingerprint = getActivity().getIntent().getBooleanExtra(
    154                     ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
    155             mForChangeCredRequiredForBoot = getArguments() != null && getArguments().getBoolean(
    156                     ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT);
    157 
    158             if (savedInstanceState != null) {
    159                 mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
    160                 mWaitingForConfirmation = savedInstanceState.getBoolean(WAITING_FOR_CONFIRMATION);
    161                 mEncryptionRequestQuality = savedInstanceState.getInt(ENCRYPT_REQUESTED_QUALITY);
    162                 mEncryptionRequestDisabled = savedInstanceState.getBoolean(
    163                         ENCRYPT_REQUESTED_DISABLED);
    164             }
    165 
    166             int targetUser = Utils.getSecureTargetUser(
    167                     getActivity().getActivityToken(),
    168                     UserManager.get(getActivity()),
    169                     null,
    170                     getActivity().getIntent().getExtras()).getIdentifier();
    171             if (DevicePolicyManager.ACTION_SET_NEW_PARENT_PROFILE_PASSWORD.equals(
    172                     getActivity().getIntent().getAction()) ||
    173                     !mLockPatternUtils.isSeparateProfileChallengeAllowed(targetUser)) {
    174                 // Always use parent if explicitely requested or if profile challenge is not
    175                 // supported
    176                 Bundle arguments = getArguments();
    177                 mUserId = Utils.getUserIdFromBundle(getContext(), arguments != null ? arguments
    178                         : getActivity().getIntent().getExtras());
    179             } else {
    180                 mUserId = targetUser;
    181             }
    182 
    183             if (DevicePolicyManager.ACTION_SET_NEW_PASSWORD
    184                     .equals(getActivity().getIntent().getAction())
    185                     && Utils.isManagedProfile(UserManager.get(getActivity()), mUserId)
    186                     && mLockPatternUtils.isSeparateProfileChallengeEnabled(mUserId)) {
    187                 getActivity().setTitle(R.string.lock_settings_picker_title_profile);
    188             }
    189 
    190             mManagedPasswordProvider = ManagedLockPasswordProvider.get(getActivity(), mUserId);
    191 
    192             if (mPasswordConfirmed) {
    193                 updatePreferencesOrFinish();
    194                 if (mForChangeCredRequiredForBoot) {
    195                     maybeEnableEncryption(mLockPatternUtils.getKeyguardStoredPasswordQuality(
    196                             mUserId), false);
    197                 }
    198             } else if (!mWaitingForConfirmation) {
    199                 ChooseLockSettingsHelper helper =
    200                         new ChooseLockSettingsHelper(this.getActivity(), this);
    201                 boolean managedProfileWithUnifiedLock = Utils
    202                         .isManagedProfile(UserManager.get(getActivity()), mUserId)
    203                         && !mLockPatternUtils.isSeparateProfileChallengeEnabled(mUserId);
    204                 if (managedProfileWithUnifiedLock
    205                         || !helper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST,
    206                         getString(R.string.unlock_set_unlock_launch_picker_title), true, mUserId)) {
    207                     mPasswordConfirmed = true; // no password set, so no need to confirm
    208                     updatePreferencesOrFinish();
    209                 } else {
    210                     mWaitingForConfirmation = true;
    211                 }
    212             }
    213             addHeaderView();
    214         }
    215 
    216         protected void addHeaderView() {
    217             if (mForFingerprint) {
    218                 setHeaderView(R.layout.choose_lock_generic_fingerprint_header);
    219             }
    220         }
    221 
    222         @Override
    223         public boolean onPreferenceTreeClick(Preference preference) {
    224             final String key = preference.getKey();
    225 
    226             if (!isUnlockMethodSecure(key) && mLockPatternUtils.isSecure(mUserId)) {
    227                 // Show the disabling FRP warning only when the user is switching from a secure
    228                 // unlock method to an insecure one
    229                 showFactoryResetProtectionWarningDialog(key);
    230                 return true;
    231             } else {
    232                 return setUnlockMethod(key);
    233             }
    234         }
    235 
    236         /**
    237          * If the device has encryption already enabled, then ask the user if they
    238          * also want to encrypt the phone with this password.
    239          *
    240          * @param quality
    241          * @param disabled
    242          */
    243         // TODO: why does this take disabled, its always called with a quality higher than
    244         // what makes sense with disabled == true
    245         private void maybeEnableEncryption(int quality, boolean disabled) {
    246             DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
    247             if (UserManager.get(getActivity()).isAdminUser()
    248                     && mUserId == UserHandle.myUserId()
    249                     && LockPatternUtils.isDeviceEncryptionEnabled()
    250                     && !LockPatternUtils.isFileEncryptionEnabled()
    251                     && !dpm.getDoNotAskCredentialsOnBoot()) {
    252                 mEncryptionRequestQuality = quality;
    253                 mEncryptionRequestDisabled = disabled;
    254                 // Get the intent that the encryption interstitial should start for creating
    255                 // the new unlock method.
    256                 Intent unlockMethodIntent = getIntentForUnlockMethod(quality, disabled);
    257                 unlockMethodIntent.putExtra(
    258                         ChooseLockSettingsHelper.EXTRA_KEY_FOR_CHANGE_CRED_REQUIRED_FOR_BOOT,
    259                         mForChangeCredRequiredForBoot);
    260                 final Context context = getActivity();
    261                 // If accessibility is enabled and the user hasn't seen this dialog before, set the
    262                 // default state to agree with that which is compatible with accessibility
    263                 // (password not required).
    264                 final boolean accEn = AccessibilityManager.getInstance(context).isEnabled();
    265                 final boolean required = mLockPatternUtils.isCredentialRequiredToDecrypt(!accEn);
    266                 Intent intent = getEncryptionInterstitialIntent(context, quality, required,
    267                         unlockMethodIntent);
    268                 intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT,
    269                         mForFingerprint);
    270                 intent.putExtra(EXTRA_HIDE_DRAWER, mHideDrawer);
    271                 startActivityForResult(intent, ENABLE_ENCRYPTION_REQUEST);
    272             } else {
    273                 if (mForChangeCredRequiredForBoot) {
    274                     // Welp, couldn't change it. Oh well.
    275                     finish();
    276                     return;
    277                 }
    278                 mRequirePassword = false; // device encryption not enabled or not device owner.
    279                 updateUnlockMethodAndFinish(quality, disabled);
    280             }
    281         }
    282 
    283         @Override
    284         public void onActivityResult(int requestCode, int resultCode, Intent data) {
    285             super.onActivityResult(requestCode, resultCode, data);
    286             mWaitingForConfirmation = false;
    287             if (requestCode == CONFIRM_EXISTING_REQUEST && resultCode == Activity.RESULT_OK) {
    288                 mPasswordConfirmed = true;
    289                 mUserPassword = data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
    290                 updatePreferencesOrFinish();
    291                 if (mForChangeCredRequiredForBoot) {
    292                     if (!TextUtils.isEmpty(mUserPassword)) {
    293                         maybeEnableEncryption(
    294                                 mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId), false);
    295                     } else {
    296                         finish();
    297                     }
    298                 }
    299             } else if (requestCode == CHOOSE_LOCK_REQUEST
    300                     || requestCode == ENABLE_ENCRYPTION_REQUEST) {
    301                 if (resultCode != RESULT_CANCELED || mForChangeCredRequiredForBoot) {
    302                     getActivity().setResult(resultCode, data);
    303                     finish();
    304                 }
    305             } else {
    306                 getActivity().setResult(Activity.RESULT_CANCELED);
    307                 finish();
    308             }
    309             if (requestCode == Activity.RESULT_CANCELED && mForChangeCredRequiredForBoot) {
    310                 finish();
    311             }
    312         }
    313 
    314         @Override
    315         public void onSaveInstanceState(Bundle outState) {
    316             super.onSaveInstanceState(outState);
    317             // Saved so we don't force user to re-enter their password if configuration changes
    318             outState.putBoolean(PASSWORD_CONFIRMED, mPasswordConfirmed);
    319             outState.putBoolean(WAITING_FOR_CONFIRMATION, mWaitingForConfirmation);
    320             outState.putInt(ENCRYPT_REQUESTED_QUALITY, mEncryptionRequestQuality);
    321             outState.putBoolean(ENCRYPT_REQUESTED_DISABLED, mEncryptionRequestDisabled);
    322         }
    323 
    324         private void updatePreferencesOrFinish() {
    325             Intent intent = getActivity().getIntent();
    326             int quality = intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, -1);
    327             if (quality == -1) {
    328                 // If caller didn't specify password quality, show UI and allow the user to choose.
    329                 quality = intent.getIntExtra(MINIMUM_QUALITY_KEY, -1);
    330                 quality = upgradeQuality(quality);
    331                 final boolean hideDisabledPrefs = intent.getBooleanExtra(
    332                         HIDE_DISABLED_PREFS, false);
    333                 final PreferenceScreen prefScreen = getPreferenceScreen();
    334                 if (prefScreen != null) {
    335                     prefScreen.removeAll();
    336                 }
    337                 addPreferences();
    338                 disableUnusablePreferences(quality, hideDisabledPrefs);
    339                 updatePreferenceText();
    340                 updateCurrentPreference();
    341                 updatePreferenceSummaryIfNeeded();
    342             } else {
    343                 updateUnlockMethodAndFinish(quality, false);
    344             }
    345         }
    346 
    347         protected void addPreferences() {
    348             addPreferencesFromResource(R.xml.security_settings_picker);
    349 
    350             // Used for testing purposes
    351             findPreference(KEY_UNLOCK_SET_NONE).setViewId(R.id.lock_none);
    352             findPreference(KEY_UNLOCK_SET_PIN).setViewId(R.id.lock_pin);
    353             findPreference(KEY_UNLOCK_SET_PASSWORD).setViewId(R.id.lock_password);
    354         }
    355 
    356         private void updatePreferenceText() {
    357             if (mForFingerprint) {
    358                 Preference pattern = findPreference(KEY_UNLOCK_SET_PATTERN);
    359                 pattern.setTitle(R.string.fingerprint_unlock_set_unlock_pattern);
    360 
    361                 Preference pin = findPreference(KEY_UNLOCK_SET_PIN);
    362                 pin.setTitle(R.string.fingerprint_unlock_set_unlock_pin);
    363 
    364                 Preference password = findPreference(KEY_UNLOCK_SET_PASSWORD);
    365                 password.setTitle(R.string.fingerprint_unlock_set_unlock_password);
    366             }
    367 
    368             if (mManagedPasswordProvider.isSettingManagedPasswordSupported()) {
    369                 Preference managed = findPreference(KEY_UNLOCK_SET_MANAGED);
    370                 managed.setTitle(mManagedPasswordProvider.getPickerOptionTitle(mForFingerprint));
    371             } else {
    372                 removePreference(KEY_UNLOCK_SET_MANAGED);
    373             }
    374         }
    375 
    376         private void updateCurrentPreference() {
    377             String currentKey = getKeyForCurrent();
    378             Preference preference = findPreference(currentKey);
    379             if (preference != null) {
    380                 preference.setSummary(R.string.current_screen_lock);
    381             }
    382         }
    383 
    384         private String getKeyForCurrent() {
    385             final int credentialOwner = UserManager.get(getContext())
    386                     .getCredentialOwnerProfile(mUserId);
    387             if (mLockPatternUtils.isLockScreenDisabled(credentialOwner)) {
    388                 return KEY_UNLOCK_SET_OFF;
    389             }
    390             switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(credentialOwner)) {
    391                 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
    392                     return KEY_UNLOCK_SET_PATTERN;
    393                 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
    394                 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
    395                     return KEY_UNLOCK_SET_PIN;
    396                 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
    397                 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
    398                 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
    399                     return KEY_UNLOCK_SET_PASSWORD;
    400                 case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
    401                     return KEY_UNLOCK_SET_MANAGED;
    402                 case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
    403                     return KEY_UNLOCK_SET_NONE;
    404             }
    405             return null;
    406         }
    407 
    408         /** increases the quality if necessary */
    409         private int upgradeQuality(int quality) {
    410             quality = upgradeQualityForDPM(quality);
    411             return quality;
    412         }
    413 
    414         private int upgradeQualityForDPM(int quality) {
    415             // Compare min allowed password quality
    416             int minQuality = mDPM.getPasswordQuality(null, mUserId);
    417             if (quality < minQuality) {
    418                 quality = minQuality;
    419             }
    420             return quality;
    421         }
    422 
    423         /***
    424          * Disables preferences that are less secure than required quality. The actual
    425          * implementation is in disableUnusablePreferenceImpl.
    426          *
    427          * @param quality the requested quality.
    428          * @param hideDisabledPrefs if false preferences show why they were disabled; otherwise
    429          * they're not shown at all.
    430          */
    431         protected void disableUnusablePreferences(final int quality, boolean hideDisabledPrefs) {
    432             disableUnusablePreferencesImpl(quality, hideDisabledPrefs);
    433         }
    434 
    435         /***
    436          * Disables preferences that are less secure than required quality.
    437          *
    438          * @param quality the requested quality.
    439          * @param hideDisabled whether to hide disable screen lock options.
    440          */
    441         protected void disableUnusablePreferencesImpl(final int quality,
    442                 boolean hideDisabled) {
    443             final PreferenceScreen entries = getPreferenceScreen();
    444 
    445             int adminEnforcedQuality = mDPM.getPasswordQuality(null, mUserId);
    446             EnforcedAdmin enforcedAdmin = RestrictedLockUtils.checkIfPasswordQualityIsSet(
    447                     getActivity(), mUserId);
    448             for (int i = entries.getPreferenceCount() - 1; i >= 0; --i) {
    449                 Preference pref = entries.getPreference(i);
    450                 if (pref instanceof RestrictedPreference) {
    451                     final String key = pref.getKey();
    452                     boolean enabled = true;
    453                     boolean visible = true;
    454                     boolean disabledByAdmin = false;
    455                     if (KEY_UNLOCK_SET_OFF.equals(key)) {
    456                         enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
    457                         if (getResources().getBoolean(R.bool.config_hide_none_security_option)) {
    458                             enabled = false;
    459                             visible = false;
    460                         }
    461                         disabledByAdmin = adminEnforcedQuality
    462                                 > DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
    463                     } else if (KEY_UNLOCK_SET_NONE.equals(key)) {
    464                         if (mUserId != UserHandle.myUserId()) {
    465                             // Swipe doesn't make sense for profiles.
    466                             visible = false;
    467                         }
    468                         enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
    469                         disabledByAdmin = adminEnforcedQuality
    470                                 > DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
    471                     } else if (KEY_UNLOCK_SET_PATTERN.equals(key)) {
    472                         enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
    473                         disabledByAdmin = adminEnforcedQuality
    474                                 > DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
    475                     } else if (KEY_UNLOCK_SET_PIN.equals(key)) {
    476                         enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
    477                         disabledByAdmin = adminEnforcedQuality
    478                                 > DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
    479                     } else if (KEY_UNLOCK_SET_PASSWORD.equals(key)) {
    480                         enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
    481                         disabledByAdmin = adminEnforcedQuality
    482                                 > DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
    483                     } else if (KEY_UNLOCK_SET_MANAGED.equals(key)) {
    484                         enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_MANAGED
    485                                 && mManagedPasswordProvider.isManagedPasswordChoosable();
    486                         disabledByAdmin = adminEnforcedQuality
    487                                 > DevicePolicyManager.PASSWORD_QUALITY_MANAGED;
    488                     }
    489                     if (hideDisabled) {
    490                         visible = enabled;
    491                     }
    492                     if (!visible) {
    493                         entries.removePreference(pref);
    494                     } else if (disabledByAdmin && enforcedAdmin != null) {
    495                         ((RestrictedPreference) pref).setDisabledByAdmin(enforcedAdmin);
    496                     } else if (!enabled) {
    497                         // we need to setDisabledByAdmin to null first to disable the padlock
    498                         // in case it was set earlier.
    499                         ((RestrictedPreference) pref).setDisabledByAdmin(null);
    500                         pref.setSummary(R.string.unlock_set_unlock_disabled_summary);
    501                         pref.setEnabled(false);
    502                     } else {
    503                         ((RestrictedPreference) pref).setDisabledByAdmin(null);
    504                     }
    505                 }
    506             }
    507         }
    508 
    509         private void updatePreferenceSummaryIfNeeded() {
    510             // On a default block encrypted device with accessibility, add a warning
    511             // that your data is not credential encrypted
    512             if (!StorageManager.isBlockEncrypted()) {
    513                 return;
    514             }
    515 
    516             if (StorageManager.isNonDefaultBlockEncrypted()) {
    517                 return;
    518             }
    519 
    520             if (AccessibilityManager.getInstance(getActivity()).getEnabledAccessibilityServiceList(
    521                     AccessibilityServiceInfo.FEEDBACK_ALL_MASK).isEmpty()) {
    522                 return;
    523             }
    524 
    525             CharSequence summary = getString(R.string.secure_lock_encryption_warning);
    526 
    527             PreferenceScreen screen = getPreferenceScreen();
    528             final int preferenceCount = screen.getPreferenceCount();
    529             for (int i = 0; i < preferenceCount; i++) {
    530                 Preference preference = screen.getPreference(i);
    531                 switch (preference.getKey()) {
    532                     case KEY_UNLOCK_SET_PATTERN:
    533                     case KEY_UNLOCK_SET_PIN:
    534                     case KEY_UNLOCK_SET_PASSWORD:
    535                     case KEY_UNLOCK_SET_MANAGED: {
    536                         preference.setSummary(summary);
    537                     } break;
    538                 }
    539             }
    540         }
    541 
    542         protected Intent getLockManagedPasswordIntent(boolean requirePassword, String password) {
    543             return mManagedPasswordProvider.createIntent(requirePassword, password);
    544         }
    545 
    546         protected Intent getLockPasswordIntent(Context context, int quality,
    547                 int minLength, final int maxLength,
    548                 boolean requirePasswordToDecrypt, boolean confirmCredentials, int userId) {
    549             return ChooseLockPassword.createIntent(context, quality, minLength,
    550                     maxLength, requirePasswordToDecrypt, confirmCredentials, userId);
    551         }
    552 
    553         protected Intent getLockPasswordIntent(Context context, int quality,
    554                 int minLength, final int maxLength,
    555                 boolean requirePasswordToDecrypt, long challenge, int userId) {
    556             return ChooseLockPassword.createIntent(context, quality, minLength,
    557                     maxLength, requirePasswordToDecrypt, challenge, userId);
    558         }
    559 
    560         protected Intent getLockPasswordIntent(Context context, int quality, int minLength,
    561                 int maxLength, boolean requirePasswordToDecrypt, String password, int userId) {
    562             return ChooseLockPassword.createIntent(context, quality, minLength, maxLength,
    563                     requirePasswordToDecrypt, password, userId);
    564         }
    565 
    566         protected Intent getLockPatternIntent(Context context, final boolean requirePassword,
    567                 final boolean confirmCredentials, int userId) {
    568             return ChooseLockPattern.createIntent(context, requirePassword,
    569                     confirmCredentials, userId);
    570         }
    571 
    572         protected Intent getLockPatternIntent(Context context, final boolean requirePassword,
    573                long challenge, int userId) {
    574             return ChooseLockPattern.createIntent(context, requirePassword, challenge, userId);
    575         }
    576 
    577         protected Intent getLockPatternIntent(Context context, final boolean requirePassword,
    578                 final String pattern, int userId) {
    579             return ChooseLockPattern.createIntent(context, requirePassword, pattern, userId);
    580         }
    581 
    582         protected Intent getEncryptionInterstitialIntent(Context context, int quality,
    583                 boolean required, Intent unlockMethodIntent) {
    584             return EncryptionInterstitial.createStartIntent(context, quality, required,
    585                     unlockMethodIntent);
    586         }
    587 
    588         /**
    589          * Invokes an activity to change the user's pattern, password or PIN based on given quality
    590          * and minimum quality specified by DevicePolicyManager. If quality is
    591          * {@link DevicePolicyManager#PASSWORD_QUALITY_UNSPECIFIED}, password is cleared.
    592          *
    593          * @param quality the desired quality. Ignored if DevicePolicyManager requires more security
    594          * @param disabled whether or not to show LockScreen at all. Only meaningful when quality is
    595          * {@link DevicePolicyManager#PASSWORD_QUALITY_UNSPECIFIED}
    596          */
    597         void updateUnlockMethodAndFinish(int quality, boolean disabled) {
    598             // Sanity check. We should never get here without confirming user's existing password.
    599             if (!mPasswordConfirmed) {
    600                 throw new IllegalStateException("Tried to update password without confirming it");
    601             }
    602 
    603             quality = upgradeQuality(quality);
    604             Intent intent = getIntentForUnlockMethod(quality, disabled);
    605             if (intent != null) {
    606                 startActivityForResult(intent, CHOOSE_LOCK_REQUEST);
    607                 return;
    608             }
    609 
    610             if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
    611                 mLockPatternUtils.setSeparateProfileChallengeEnabled(mUserId, true, mUserPassword);
    612                 mChooseLockSettingsHelper.utils().clearLock(mUserId);
    613                 mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled, mUserId);
    614                 removeAllFingerprintForUserAndFinish(mUserId);
    615                 getActivity().setResult(Activity.RESULT_OK);
    616             } else {
    617                 removeAllFingerprintForUserAndFinish(mUserId);
    618             }
    619         }
    620 
    621         private Intent getIntentForUnlockMethod(int quality, boolean disabled) {
    622             Intent intent = null;
    623             final Context context = getActivity();
    624             if (quality >= DevicePolicyManager.PASSWORD_QUALITY_MANAGED) {
    625                 intent = getLockManagedPasswordIntent(mRequirePassword, mUserPassword);
    626             } else if (quality >= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) {
    627                 int minLength = mDPM.getPasswordMinimumLength(null, mUserId);
    628                 if (minLength < MIN_PASSWORD_LENGTH) {
    629                     minLength = MIN_PASSWORD_LENGTH;
    630                 }
    631                 final int maxLength = mDPM.getPasswordMaximumLength(quality);
    632                 if (mHasChallenge) {
    633                     intent = getLockPasswordIntent(context, quality, minLength,
    634                             maxLength, mRequirePassword, mChallenge, mUserId);
    635                 } else {
    636                     intent = getLockPasswordIntent(context, quality, minLength,
    637                             maxLength, mRequirePassword, mUserPassword, mUserId);
    638                 }
    639             } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
    640                 if (mHasChallenge) {
    641                     intent = getLockPatternIntent(context, mRequirePassword,
    642                             mChallenge, mUserId);
    643                 } else {
    644                     intent = getLockPatternIntent(context, mRequirePassword,
    645                             mUserPassword, mUserId);
    646                 }
    647             }
    648             if (intent != null) {
    649                 intent.putExtra(EXTRA_HIDE_DRAWER, mHideDrawer);
    650             }
    651             return intent;
    652         }
    653 
    654         private void removeAllFingerprintForUserAndFinish(final int userId) {
    655             if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) {
    656                 if (mFingerprintManager.hasEnrolledFingerprints(userId)) {
    657                     mFingerprintManager.setActiveUser(userId);
    658                     // For the purposes of M and N, groupId is the same as userId.
    659                     final int groupId = userId;
    660                     Fingerprint finger = new Fingerprint(null, groupId, 0, 0);
    661                     mFingerprintManager.remove(finger, userId,
    662                             new RemovalCallback() {
    663                                 @Override
    664                                 public void onRemovalError(Fingerprint fp, int errMsgId,
    665                                         CharSequence errString) {
    666                                     Log.v(TAG, "Fingerprint removed: " + fp.getFingerId());
    667                                     if (fp.getFingerId() == 0) {
    668                                         removeManagedProfileFingerprintsAndFinishIfNecessary(userId);
    669                                     }
    670                                 }
    671 
    672                                 @Override
    673                                 public void onRemovalSucceeded(Fingerprint fingerprint) {
    674                                     if (fingerprint.getFingerId() == 0) {
    675                                         removeManagedProfileFingerprintsAndFinishIfNecessary(userId);
    676                                     }
    677                                 }
    678                             });
    679                 } else {
    680                     // No fingerprints in this user, we may also want to delete managed profile
    681                     // fingerprints
    682                     removeManagedProfileFingerprintsAndFinishIfNecessary(userId);
    683                 }
    684             } else {
    685                 // The removal callback will call finish, once all fingerprints are removed.
    686                 // We need to wait for that to occur, otherwise, the UI will still show that
    687                 // fingerprints exist even though they are (about to) be removed depending on
    688                 // the race condition.
    689                 finish();
    690             }
    691         }
    692 
    693         private void removeManagedProfileFingerprintsAndFinishIfNecessary(final int parentUserId) {
    694             mFingerprintManager.setActiveUser(UserHandle.myUserId());
    695             final UserManager um = UserManager.get(getActivity());
    696             boolean hasChildProfile = false;
    697             if (!um.getUserInfo(parentUserId).isManagedProfile()) {
    698                 // Current user is primary profile, remove work profile fingerprints if necessary
    699                 final List<UserInfo> profiles = um.getProfiles(parentUserId);
    700                 final int profilesSize = profiles.size();
    701                 for (int i = 0; i < profilesSize; i++) {
    702                     final UserInfo userInfo = profiles.get(i);
    703                     if (userInfo.isManagedProfile() && !mLockPatternUtils
    704                             .isSeparateProfileChallengeEnabled(userInfo.id)) {
    705                         removeAllFingerprintForUserAndFinish(userInfo.id);
    706                         hasChildProfile = true;
    707                         break;
    708                     }
    709                 }
    710             }
    711             if (!hasChildProfile) {
    712                 finish();
    713             }
    714         }
    715 
    716         @Override
    717         public void onDestroy() {
    718             super.onDestroy();
    719         }
    720 
    721         @Override
    722         protected int getHelpResource() {
    723             return R.string.help_url_choose_lockscreen;
    724         }
    725 
    726         private int getResIdForFactoryResetProtectionWarningTitle() {
    727             boolean isProfile = Utils.isManagedProfile(UserManager.get(getActivity()), mUserId);
    728             return isProfile ? R.string.unlock_disable_frp_warning_title_profile
    729                     : R.string.unlock_disable_frp_warning_title;
    730         }
    731 
    732         private int getResIdForFactoryResetProtectionWarningMessage() {
    733             boolean hasFingerprints = mFingerprintManager.hasEnrolledFingerprints(mUserId);
    734             boolean isProfile = Utils.isManagedProfile(UserManager.get(getActivity()), mUserId);
    735             switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(mUserId)) {
    736                 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
    737                     if (hasFingerprints && isProfile) {
    738                         return R.string
    739                                 .unlock_disable_frp_warning_content_pattern_fingerprint_profile;
    740                     } else if (hasFingerprints && !isProfile) {
    741                         return R.string.unlock_disable_frp_warning_content_pattern_fingerprint;
    742                     } else if (isProfile) {
    743                         return R.string.unlock_disable_frp_warning_content_pattern_profile;
    744                     } else {
    745                         return R.string.unlock_disable_frp_warning_content_pattern;
    746                     }
    747                 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
    748                 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
    749                     if (hasFingerprints && isProfile) {
    750                         return R.string.unlock_disable_frp_warning_content_pin_fingerprint_profile;
    751                     } else if (hasFingerprints && !isProfile) {
    752                         return R.string.unlock_disable_frp_warning_content_pin_fingerprint;
    753                     } else if (isProfile) {
    754                         return R.string.unlock_disable_frp_warning_content_pin_profile;
    755                     } else {
    756                         return R.string.unlock_disable_frp_warning_content_pin;
    757                     }
    758                 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
    759                 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
    760                 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
    761                 case DevicePolicyManager.PASSWORD_QUALITY_MANAGED:
    762                     if (hasFingerprints && isProfile) {
    763                         return R.string
    764                                 .unlock_disable_frp_warning_content_password_fingerprint_profile;
    765                     } else if (hasFingerprints && !isProfile) {
    766                         return R.string.unlock_disable_frp_warning_content_password_fingerprint;
    767                     } else if (isProfile) {
    768                         return R.string.unlock_disable_frp_warning_content_password_profile;
    769                     } else {
    770                         return R.string.unlock_disable_frp_warning_content_password;
    771                     }
    772                 default:
    773                     if (hasFingerprints && isProfile) {
    774                         return R.string
    775                                 .unlock_disable_frp_warning_content_unknown_fingerprint_profile;
    776                     } else if (hasFingerprints && !isProfile) {
    777                         return R.string.unlock_disable_frp_warning_content_unknown_fingerprint;
    778                     } else if (isProfile) {
    779                         return R.string.unlock_disable_frp_warning_content_unknown_profile;
    780                     } else {
    781                         return R.string.unlock_disable_frp_warning_content_unknown;
    782                     }
    783             }
    784         }
    785 
    786         private boolean isUnlockMethodSecure(String unlockMethod) {
    787             return !(KEY_UNLOCK_SET_OFF.equals(unlockMethod) ||
    788                     KEY_UNLOCK_SET_NONE.equals(unlockMethod));
    789         }
    790 
    791         private boolean setUnlockMethod(String unlockMethod) {
    792             EventLog.writeEvent(EventLogTags.LOCK_SCREEN_TYPE, unlockMethod);
    793 
    794             if (KEY_UNLOCK_SET_OFF.equals(unlockMethod)) {
    795                 updateUnlockMethodAndFinish(
    796                         DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, true /* disabled */ );
    797             } else if (KEY_UNLOCK_SET_NONE.equals(unlockMethod)) {
    798                 updateUnlockMethodAndFinish(
    799                         DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, false /* disabled */ );
    800             } else if (KEY_UNLOCK_SET_MANAGED.equals(unlockMethod)) {
    801                 maybeEnableEncryption(DevicePolicyManager.PASSWORD_QUALITY_MANAGED, false);
    802             } else if (KEY_UNLOCK_SET_PATTERN.equals(unlockMethod)) {
    803                 maybeEnableEncryption(
    804                         DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, false);
    805             } else if (KEY_UNLOCK_SET_PIN.equals(unlockMethod)) {
    806                 maybeEnableEncryption(
    807                         DevicePolicyManager.PASSWORD_QUALITY_NUMERIC, false);
    808             } else if (KEY_UNLOCK_SET_PASSWORD.equals(unlockMethod)) {
    809                 maybeEnableEncryption(
    810                         DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC, false);
    811             } else {
    812                 Log.e(TAG, "Encountered unknown unlock method to set: " + unlockMethod);
    813                 return false;
    814             }
    815             return true;
    816         }
    817 
    818         private void showFactoryResetProtectionWarningDialog(String unlockMethodToSet) {
    819             int title = getResIdForFactoryResetProtectionWarningTitle();
    820             int message = getResIdForFactoryResetProtectionWarningMessage();
    821             FactoryResetProtectionWarningDialog dialog =
    822                     FactoryResetProtectionWarningDialog.newInstance(
    823                             title, message, unlockMethodToSet);
    824             dialog.show(getChildFragmentManager(), TAG_FRP_WARNING_DIALOG);
    825         }
    826 
    827         public static class FactoryResetProtectionWarningDialog extends DialogFragment {
    828 
    829             private static final String ARG_TITLE_RES = "titleRes";
    830             private static final String ARG_MESSAGE_RES = "messageRes";
    831             private static final String ARG_UNLOCK_METHOD_TO_SET = "unlockMethodToSet";
    832 
    833             public static FactoryResetProtectionWarningDialog newInstance(
    834                     int titleRes, int messageRes, String unlockMethodToSet) {
    835                 FactoryResetProtectionWarningDialog frag =
    836                         new FactoryResetProtectionWarningDialog();
    837                 Bundle args = new Bundle();
    838                 args.putInt(ARG_TITLE_RES, titleRes);
    839                 args.putInt(ARG_MESSAGE_RES, messageRes);
    840                 args.putString(ARG_UNLOCK_METHOD_TO_SET, unlockMethodToSet);
    841                 frag.setArguments(args);
    842                 return frag;
    843             }
    844 
    845             @Override
    846             public void show(FragmentManager manager, String tag) {
    847                 if (manager.findFragmentByTag(tag) == null) {
    848                     // Prevent opening multiple dialogs if tapped on button quickly
    849                     super.show(manager, tag);
    850                 }
    851             }
    852 
    853             @Override
    854             public Dialog onCreateDialog(Bundle savedInstanceState) {
    855                 final Bundle args = getArguments();
    856 
    857                 return new AlertDialog.Builder(getActivity())
    858                         .setTitle(args.getInt(ARG_TITLE_RES))
    859                         .setMessage(args.getInt(ARG_MESSAGE_RES))
    860                         .setPositiveButton(R.string.unlock_disable_frp_warning_ok,
    861                                 new DialogInterface.OnClickListener() {
    862                                     @Override
    863                                     public void onClick(DialogInterface dialog, int whichButton) {
    864                                         ((ChooseLockGenericFragment) getParentFragment())
    865                                                 .setUnlockMethod(
    866                                                         args.getString(ARG_UNLOCK_METHOD_TO_SET));
    867                                     }
    868                                 }
    869                         )
    870                         .setNegativeButton(R.string.cancel,
    871                                 new DialogInterface.OnClickListener() {
    872                                     @Override
    873                                     public void onClick(DialogInterface dialog, int whichButton) {
    874                                         dismiss();
    875                                     }
    876                                 }
    877                         )
    878                         .create();
    879             }
    880         }
    881     }
    882 }
    883