ChooseLockGeneric.java revision c474a88c2de30ea93ae03221b70e6365bb7f5f34
1abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn/*
2abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn * Copyright (C) 2010 The Android Open Source Project
3abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn *
4abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
5abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn * you may not use this file except in compliance with the License.
6abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn * You may obtain a copy of the License at
7abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn *
8abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
9abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn *
10abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn * Unless required by applicable law or agreed to in writing, software
11abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
12abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn * See the License for the specific language governing permissions and
14abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn * limitations under the License.
15abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn */
16abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn
17abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackbornpackage com.android.settings;
18abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn
1917e9e1933055b207473b488595b2887bfcaea32eJim Millerimport android.app.Activity;
205541a86efe5f26956e54de49c4a59bf1dab79a78Jim Millerimport android.app.PendingIntent;
214037c7f27c849a1ada0980ad881636fc940a0b85Dianne Hackbornimport android.app.admin.DevicePolicyManager;
22abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackbornimport android.content.Context;
23abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackbornimport android.content.Intent;
24abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackbornimport android.os.Bundle;
255541a86efe5f26956e54de49c4a59bf1dab79a78Jim Millerimport android.os.SystemProperties;
26bbb4afa19f75694c585506b0c091372d60e07ca7Jim Millerimport android.preference.Preference;
27bbb4afa19f75694c585506b0c091372d60e07ca7Jim Millerimport android.preference.PreferenceActivity;
28bbb4afa19f75694c585506b0c091372d60e07ca7Jim Millerimport android.preference.PreferenceCategory;
29bbb4afa19f75694c585506b0c091372d60e07ca7Jim Millerimport android.preference.PreferenceScreen;
30d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstromimport android.security.KeyStore;
31bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller
326465054995f8470e52ecaf68ea9508a28f8a5363Gilles Debunneimport com.android.internal.widget.LockPatternUtils;
336465054995f8470e52ecaf68ea9508a28f8a5363Gilles Debunne
34bbb4afa19f75694c585506b0c091372d60e07ca7Jim Millerpublic class ChooseLockGeneric extends PreferenceActivity {
35abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn
36abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn    @Override
3717e9e1933055b207473b488595b2887bfcaea32eJim Miller    public Intent getIntent() {
3817e9e1933055b207473b488595b2887bfcaea32eJim Miller        Intent modIntent = new Intent(super.getIntent());
3917e9e1933055b207473b488595b2887bfcaea32eJim Miller        modIntent.putExtra(EXTRA_SHOW_FRAGMENT, ChooseLockGenericFragment.class.getName());
4017e9e1933055b207473b488595b2887bfcaea32eJim Miller        modIntent.putExtra(EXTRA_NO_HEADERS, true);
4117e9e1933055b207473b488595b2887bfcaea32eJim Miller        return modIntent;
4217e9e1933055b207473b488595b2887bfcaea32eJim Miller    }
43bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller
4417e9e1933055b207473b488595b2887bfcaea32eJim Miller    public static class ChooseLockGenericFragment extends SettingsPreferenceFragment {
4517e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final int MIN_PASSWORD_LENGTH = 4;
4617e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final String KEY_UNLOCK_SET_OFF = "unlock_set_off";
4717e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final String KEY_UNLOCK_SET_NONE = "unlock_set_none";
485541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller        private static final String KEY_UNLOCK_SET_BIOMETRIC_WEAK = "unlock_set_biometric_weak";
4917e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final String KEY_UNLOCK_SET_PIN = "unlock_set_pin";
5017e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final String KEY_UNLOCK_SET_PASSWORD = "unlock_set_password";
5117e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final String KEY_UNLOCK_SET_PATTERN = "unlock_set_pattern";
5217e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final int CONFIRM_EXISTING_REQUEST = 100;
5317e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final String PASSWORD_CONFIRMED = "password_confirmed";
5417e9e1933055b207473b488595b2887bfcaea32eJim Miller        private static final String CONFIRM_CREDENTIALS = "confirm_credentials";
55d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom        public static final String MINIMUM_QUALITY_KEY = "minimum_quality";
5617e9e1933055b207473b488595b2887bfcaea32eJim Miller
5717e9e1933055b207473b488595b2887bfcaea32eJim Miller        private ChooseLockSettingsHelper mChooseLockSettingsHelper;
5817e9e1933055b207473b488595b2887bfcaea32eJim Miller        private DevicePolicyManager mDPM;
59d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom        private KeyStore mKeyStore;
6017e9e1933055b207473b488595b2887bfcaea32eJim Miller        private boolean mPasswordConfirmed = false;
6117e9e1933055b207473b488595b2887bfcaea32eJim Miller
6217e9e1933055b207473b488595b2887bfcaea32eJim Miller        @Override
6317e9e1933055b207473b488595b2887bfcaea32eJim Miller        public void onCreate(Bundle savedInstanceState) {
6417e9e1933055b207473b488595b2887bfcaea32eJim Miller            super.onCreate(savedInstanceState);
6517e9e1933055b207473b488595b2887bfcaea32eJim Miller
6617e9e1933055b207473b488595b2887bfcaea32eJim Miller            mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
67d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom            mKeyStore = KeyStore.getInstance();
6817e9e1933055b207473b488595b2887bfcaea32eJim Miller            mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this.getActivity());
6917e9e1933055b207473b488595b2887bfcaea32eJim Miller
70c474a88c2de30ea93ae03221b70e6365bb7f5f34Danielle Millett            // Defaults to needing to confirm credentials
71c474a88c2de30ea93ae03221b70e6365bb7f5f34Danielle Millett            final boolean confirmCredentials = getActivity().getIntent()
72c474a88c2de30ea93ae03221b70e6365bb7f5f34Danielle Millett                .getBooleanExtra(CONFIRM_CREDENTIALS, true);
73c474a88c2de30ea93ae03221b70e6365bb7f5f34Danielle Millett            mPasswordConfirmed = !confirmCredentials;
74c474a88c2de30ea93ae03221b70e6365bb7f5f34Danielle Millett
7517e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (savedInstanceState != null) {
7617e9e1933055b207473b488595b2887bfcaea32eJim Miller                mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
7717e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
78bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller
7917e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (!mPasswordConfirmed) {
806370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                ChooseLockSettingsHelper helper =
816370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                        new ChooseLockSettingsHelper(this.getActivity(), this);
8217e9e1933055b207473b488595b2887bfcaea32eJim Miller                if (!helper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST, null, null)) {
8317e9e1933055b207473b488595b2887bfcaea32eJim Miller                    mPasswordConfirmed = true; // no password set, so no need to confirm
8417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    updatePreferencesOrFinish();
8517e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
8617e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else {
87bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller                updatePreferencesOrFinish();
88bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller            }
89bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller        }
90bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller
9117e9e1933055b207473b488595b2887bfcaea32eJim Miller        @Override
9217e9e1933055b207473b488595b2887bfcaea32eJim Miller        public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
9317e9e1933055b207473b488595b2887bfcaea32eJim Miller                Preference preference) {
9417e9e1933055b207473b488595b2887bfcaea32eJim Miller            final String key = preference.getKey();
9517e9e1933055b207473b488595b2887bfcaea32eJim Miller            boolean handled = true;
9617e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (KEY_UNLOCK_SET_OFF.equals(key)) {
976370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                updateUnlockMethodAndFinish(
986370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                        DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, true);
9917e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else if (KEY_UNLOCK_SET_NONE.equals(key)) {
1006370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                updateUnlockMethodAndFinish(
1016370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                        DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, false);
1025541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            } else if (KEY_UNLOCK_SET_BIOMETRIC_WEAK.equals(key)) {
1035541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                updateUnlockMethodAndFinish(
1045541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                        DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK, false);
1055541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            }else if (KEY_UNLOCK_SET_PATTERN.equals(key)) {
1066370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                updateUnlockMethodAndFinish(
1076370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                        DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, false);
10817e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else if (KEY_UNLOCK_SET_PIN.equals(key)) {
1096370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                updateUnlockMethodAndFinish(
1106370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                        DevicePolicyManager.PASSWORD_QUALITY_NUMERIC, false);
11117e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else if (KEY_UNLOCK_SET_PASSWORD.equals(key)) {
1126370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                updateUnlockMethodAndFinish(
1136370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                        DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC, false);
11417e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else {
11517e9e1933055b207473b488595b2887bfcaea32eJim Miller                handled = false;
11617e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
11717e9e1933055b207473b488595b2887bfcaea32eJim Miller            return handled;
118bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller        }
119bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller
12017e9e1933055b207473b488595b2887bfcaea32eJim Miller        @Override
12117e9e1933055b207473b488595b2887bfcaea32eJim Miller        public void onActivityResult(int requestCode, int resultCode, Intent data) {
12217e9e1933055b207473b488595b2887bfcaea32eJim Miller            super.onActivityResult(requestCode, resultCode, data);
12317e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (requestCode == CONFIRM_EXISTING_REQUEST && resultCode == Activity.RESULT_OK) {
12417e9e1933055b207473b488595b2887bfcaea32eJim Miller                mPasswordConfirmed = true;
12517e9e1933055b207473b488595b2887bfcaea32eJim Miller                updatePreferencesOrFinish();
12617e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else {
12717e9e1933055b207473b488595b2887bfcaea32eJim Miller                getActivity().setResult(Activity.RESULT_CANCELED);
12817e9e1933055b207473b488595b2887bfcaea32eJim Miller                finish();
12917e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
130bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller        }
131bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller
13217e9e1933055b207473b488595b2887bfcaea32eJim Miller        @Override
13317e9e1933055b207473b488595b2887bfcaea32eJim Miller        public void onSaveInstanceState(Bundle outState) {
13417e9e1933055b207473b488595b2887bfcaea32eJim Miller            super.onSaveInstanceState(outState);
13517e9e1933055b207473b488595b2887bfcaea32eJim Miller            // Saved so we don't force user to re-enter their password if configuration changes
13617e9e1933055b207473b488595b2887bfcaea32eJim Miller            outState.putBoolean(PASSWORD_CONFIRMED, mPasswordConfirmed);
13717e9e1933055b207473b488595b2887bfcaea32eJim Miller        }
138bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller
13917e9e1933055b207473b488595b2887bfcaea32eJim Miller        private void updatePreferencesOrFinish() {
1405541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            Intent intent = getActivity().getIntent();
1415541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            int quality = intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, -1);
14217e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (quality == -1) {
1436370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                // If caller didn't specify password quality, show UI and allow the user to choose.
1445541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                quality = intent.getIntExtra(MINIMUM_QUALITY_KEY, -1);
145d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom                quality = upgradeQuality(quality);
14617e9e1933055b207473b488595b2887bfcaea32eJim Miller                final PreferenceScreen prefScreen = getPreferenceScreen();
14717e9e1933055b207473b488595b2887bfcaea32eJim Miller                if (prefScreen != null) {
14817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    prefScreen.removeAll();
14917e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
15017e9e1933055b207473b488595b2887bfcaea32eJim Miller                addPreferencesFromResource(R.xml.security_settings_picker);
1516370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                disableUnusablePreferences(quality);
15217e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else {
15317e9e1933055b207473b488595b2887bfcaea32eJim Miller                updateUnlockMethodAndFinish(quality, false);
154bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller            }
155abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn        }
156bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller
157d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom        private int upgradeQuality(int quality) {
158d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom            quality = upgradeQualityForDPM(quality);
159d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom            quality = upgradeQualityForEncryption(quality);
160d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom            quality = upgradeQualityForKeyStore(quality);
161d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom            return quality;
162d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom        }
163d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom
164d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom        private int upgradeQualityForDPM(int quality) {
165d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom            // Compare min allowed password quality
166d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom            int minQuality = mDPM.getPasswordQuality(null);
167d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom            if (quality < minQuality) {
168d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom                quality = minQuality;
169d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom            }
170d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom            return quality;
171d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom        }
172d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom
1736370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler        /**
1746370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler         * Mix in "encryption minimums" to any given quality value.  This prevents users
1756370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler         * from downgrading the pattern/pin/password to a level below the minimums.
1766370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler         *
1776370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler         * ASSUMPTION:  Setting quality is sufficient (e.g. minimum lengths will be set
1786370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler         * appropriately.)
1796370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler         */
1806370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler        private int upgradeQualityForEncryption(int quality) {
1816370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler            int encryptionStatus = mDPM.getStorageEncryptionStatus();
1826370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler            boolean encrypted = (encryptionStatus == DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE)
1836370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                    || (encryptionStatus == DevicePolicyManager.ENCRYPTION_STATUS_ACTIVATING);
1846370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler            if (encrypted) {
185d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom                if (quality < CryptKeeperSettings.MIN_PASSWORD_QUALITY) {
186d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom                    quality = CryptKeeperSettings.MIN_PASSWORD_QUALITY;
187d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom                }
188d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom            }
189d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom            return quality;
190d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom        }
191d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom
192d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom        private int upgradeQualityForKeyStore(int quality) {
193d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom            if (!mKeyStore.isEmpty()) {
194d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom                if (quality < CredentialStorage.MIN_PASSWORD_QUALITY) {
195d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom                    quality = CredentialStorage.MIN_PASSWORD_QUALITY;
1966370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                }
1976370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler            }
1986370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler            return quality;
1996370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler        }
2006370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler
20117e9e1933055b207473b488595b2887bfcaea32eJim Miller        /***
20217e9e1933055b207473b488595b2887bfcaea32eJim Miller         * Disables preferences that are less secure than required quality.
20317e9e1933055b207473b488595b2887bfcaea32eJim Miller         *
20417e9e1933055b207473b488595b2887bfcaea32eJim Miller         * @param quality the requested quality.
20517e9e1933055b207473b488595b2887bfcaea32eJim Miller         */
20617e9e1933055b207473b488595b2887bfcaea32eJim Miller        private void disableUnusablePreferences(final int quality) {
2076370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler            final Preference picker =
2086370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                    getPreferenceScreen().findPreference("security_picker_category");
20917e9e1933055b207473b488595b2887bfcaea32eJim Miller            final PreferenceCategory cat = (PreferenceCategory) picker;
21017e9e1933055b207473b488595b2887bfcaea32eJim Miller            final int preferenceCount = cat.getPreferenceCount();
2115541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            final boolean onlyShowFallback = getActivity().getIntent()
2125541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                    .getBooleanExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK, false);
2135541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            final boolean weakBiometricAvailable = isBiometricSensorAvailable(
2145541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                    DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK);
2155541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            for (int i = preferenceCount-1; i >= 0; --i) {
21617e9e1933055b207473b488595b2887bfcaea32eJim Miller                Preference pref = cat.getPreference(i);
21717e9e1933055b207473b488595b2887bfcaea32eJim Miller                if (pref instanceof PreferenceScreen) {
21817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    final String key = ((PreferenceScreen) pref).getKey();
21917e9e1933055b207473b488595b2887bfcaea32eJim Miller                    boolean enabled = true;
2205541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                    boolean visible = true;
22117e9e1933055b207473b488595b2887bfcaea32eJim Miller                    if (KEY_UNLOCK_SET_OFF.equals(key)) {
22217e9e1933055b207473b488595b2887bfcaea32eJim Miller                        enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
22317e9e1933055b207473b488595b2887bfcaea32eJim Miller                    } else if (KEY_UNLOCK_SET_NONE.equals(key)) {
22417e9e1933055b207473b488595b2887bfcaea32eJim Miller                        enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
2255541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                    } else if (KEY_UNLOCK_SET_BIOMETRIC_WEAK.equals(key)) {
2265541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                        enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK;
2275541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                        visible = weakBiometricAvailable; // If not available, then don't show it.
22817e9e1933055b207473b488595b2887bfcaea32eJim Miller                    } else if (KEY_UNLOCK_SET_PATTERN.equals(key)) {
22917e9e1933055b207473b488595b2887bfcaea32eJim Miller                        enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
23017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    } else if (KEY_UNLOCK_SET_PIN.equals(key)) {
23117e9e1933055b207473b488595b2887bfcaea32eJim Miller                        enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC;
23217e9e1933055b207473b488595b2887bfcaea32eJim Miller                    } else if (KEY_UNLOCK_SET_PASSWORD.equals(key)) {
23317e9e1933055b207473b488595b2887bfcaea32eJim Miller                        enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
23417e9e1933055b207473b488595b2887bfcaea32eJim Miller                    }
2355541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                    if (!visible || (onlyShowFallback && !allowedForFallback(key))) {
2365541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                        cat.removePreference(pref);
2375541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                    } else if (!enabled) {
23817e9e1933055b207473b488595b2887bfcaea32eJim Miller                        pref.setSummary(R.string.unlock_set_unlock_disabled_summary);
23917e9e1933055b207473b488595b2887bfcaea32eJim Miller                        pref.setEnabled(false);
24017e9e1933055b207473b488595b2887bfcaea32eJim Miller                    }
241bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller                }
242bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller            }
243bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller        }
244bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller
24517e9e1933055b207473b488595b2887bfcaea32eJim Miller        /**
2465541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller         * Check whether the key is allowed for fallback (e.g. bio sensor). Returns true if it's
2475541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller         * supported as a backup.
2485541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller         *
2495541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller         * @param key
2505541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller         * @return true if allowed
2515541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller         */
2525541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller        private boolean allowedForFallback(String key) {
2535541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            return KEY_UNLOCK_SET_PATTERN.equals(key) || KEY_UNLOCK_SET_PIN.equals(key);
2545541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller        }
2555541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller
2565541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller        private boolean isBiometricSensorAvailable(int quality) {
2575541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            return SystemProperties.getBoolean("ro.lockscreen.facelock_enabled", false);
2585541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller        }
2595541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller
2605541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller        private Intent getBiometricSensorIntent(int quality) {
2615541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            Intent fallBackIntent = new Intent().setClass(getActivity(), ChooseLockGeneric.class);
2625541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            fallBackIntent.putExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK, true);
2635541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            fallBackIntent.putExtra(CONFIRM_CREDENTIALS, false);
2645541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            fallBackIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
2655541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller
2665541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            Intent intent = new Intent().setClassName("com.android.facelock",
2675541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                    "com.android.facelock.SetupFaceLock");
2685541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            PendingIntent pending = PendingIntent.getActivity(getActivity(), 0, fallBackIntent, 0);
2695541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            intent.putExtra("PendingIntent", pending);
2705541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            return intent;
2715541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller        }
2725541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller
2735541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller        /**
27417e9e1933055b207473b488595b2887bfcaea32eJim Miller         * Invokes an activity to change the user's pattern, password or PIN based on given quality
27517e9e1933055b207473b488595b2887bfcaea32eJim Miller         * and minimum quality specified by DevicePolicyManager. If quality is
27617e9e1933055b207473b488595b2887bfcaea32eJim Miller         * {@link DevicePolicyManager#PASSWORD_QUALITY_UNSPECIFIED}, password is cleared.
27717e9e1933055b207473b488595b2887bfcaea32eJim Miller         *
2786370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler         * @param quality the desired quality. Ignored if DevicePolicyManager requires more security
27917e9e1933055b207473b488595b2887bfcaea32eJim Miller         * @param disabled whether or not to show LockScreen at all. Only meaningful when quality is
28017e9e1933055b207473b488595b2887bfcaea32eJim Miller         * {@link DevicePolicyManager#PASSWORD_QUALITY_UNSPECIFIED}
28117e9e1933055b207473b488595b2887bfcaea32eJim Miller         */
28217e9e1933055b207473b488595b2887bfcaea32eJim Miller        void updateUnlockMethodAndFinish(int quality, boolean disabled) {
2836370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler            // Sanity check. We should never get here without confirming user's existing password.
28417e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (!mPasswordConfirmed) {
2856370c87a6b98abfc6badb31070a60f84b3f528b3Andy Stadler                throw new IllegalStateException("Tried to update password without confirming it");
28617e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
287bbb4afa19f75694c585506b0c091372d60e07ca7Jim Miller
2885541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            final boolean isFallback = getActivity().getIntent()
2895541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                .getBooleanExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK, false);
2905541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller
291d4023b7cca11e33e84df39dee9e9a737efab47c2Brian Carlstrom            quality = upgradeQuality(quality);
29217e9e1933055b207473b488595b2887bfcaea32eJim Miller            if (quality >= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) {
29317e9e1933055b207473b488595b2887bfcaea32eJim Miller                int minLength = mDPM.getPasswordMinimumLength(null);
29417e9e1933055b207473b488595b2887bfcaea32eJim Miller                if (minLength < MIN_PASSWORD_LENGTH) {
29517e9e1933055b207473b488595b2887bfcaea32eJim Miller                    minLength = MIN_PASSWORD_LENGTH;
29617e9e1933055b207473b488595b2887bfcaea32eJim Miller                }
29717e9e1933055b207473b488595b2887bfcaea32eJim Miller                final int maxLength = mDPM.getPasswordMaximumLength(quality);
29817e9e1933055b207473b488595b2887bfcaea32eJim Miller                Intent intent = new Intent().setClass(getActivity(), ChooseLockPassword.class);
29917e9e1933055b207473b488595b2887bfcaea32eJim Miller                intent.putExtra(LockPatternUtils.PASSWORD_TYPE_KEY, quality);
30017e9e1933055b207473b488595b2887bfcaea32eJim Miller                intent.putExtra(ChooseLockPassword.PASSWORD_MIN_KEY, minLength);
30117e9e1933055b207473b488595b2887bfcaea32eJim Miller                intent.putExtra(ChooseLockPassword.PASSWORD_MAX_KEY, maxLength);
30217e9e1933055b207473b488595b2887bfcaea32eJim Miller                intent.putExtra(CONFIRM_CREDENTIALS, false);
30317e9e1933055b207473b488595b2887bfcaea32eJim Miller                intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
3045541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                intent.putExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK,
3055541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                        isFallback);
30617e9e1933055b207473b488595b2887bfcaea32eJim Miller                startActivity(intent);
30717e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
30817e9e1933055b207473b488595b2887bfcaea32eJim Miller                boolean showTutorial = !mChooseLockSettingsHelper.utils().isPatternEverChosen();
30917e9e1933055b207473b488595b2887bfcaea32eJim Miller                Intent intent = new Intent();
31017e9e1933055b207473b488595b2887bfcaea32eJim Miller                intent.setClass(getActivity(), showTutorial
31117e9e1933055b207473b488595b2887bfcaea32eJim Miller                        ? ChooseLockPatternTutorial.class
31217e9e1933055b207473b488595b2887bfcaea32eJim Miller                        : ChooseLockPattern.class);
31317e9e1933055b207473b488595b2887bfcaea32eJim Miller                intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
31417e9e1933055b207473b488595b2887bfcaea32eJim Miller                intent.putExtra("key_lock_method", "pattern");
31517e9e1933055b207473b488595b2887bfcaea32eJim Miller                intent.putExtra(CONFIRM_CREDENTIALS, false);
3165541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                intent.putExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK,
3175541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                        isFallback);
3185541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                startActivity(intent);
3195541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller            } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) {
3205541a86efe5f26956e54de49c4a59bf1dab79a78Jim Miller                Intent intent = getBiometricSensorIntent(quality);
32117e9e1933055b207473b488595b2887bfcaea32eJim Miller                startActivity(intent);
32217e9e1933055b207473b488595b2887bfcaea32eJim Miller            } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
32317e9e1933055b207473b488595b2887bfcaea32eJim Miller                mChooseLockSettingsHelper.utils().clearLock();
32417e9e1933055b207473b488595b2887bfcaea32eJim Miller                mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled);
32517e9e1933055b207473b488595b2887bfcaea32eJim Miller                getActivity().setResult(Activity.RESULT_OK);
32617e9e1933055b207473b488595b2887bfcaea32eJim Miller            }
32717e9e1933055b207473b488595b2887bfcaea32eJim Miller            finish();
328abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn        }
329abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn    }
330abc3dc64cf61c9f5c28b6f2640b221d63cb86a0aDianne Hackborn}
331