blob: a3bd5a108c606e3f9eb6de24d719d6deae15cff1 [file] [log] [blame]
Dianne Hackbornabc3dc62010-01-20 13:40:19 -08001/*
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
17package com.android.settings;
18
Svetoslav52448442014-09-29 18:15:45 -070019import android.accessibilityservice.AccessibilityServiceInfo;
Jim Miller17e9e192010-12-07 20:41:41 -080020import android.app.Activity;
Lucky Zhang3bcea022014-11-25 18:22:14 -080021import android.app.AlertDialog;
22import android.app.Dialog;
23import android.app.DialogFragment;
Maurice Lam52c75ba2014-11-25 14:06:38 -080024import android.app.Fragment;
Lucky Zhang3bcea022014-11-25 18:22:14 -080025import android.app.FragmentManager;
Dianne Hackborn4037c7f2010-02-26 17:26:55 -080026import android.app.admin.DevicePolicyManager;
Dianne Hackbornabc3dc62010-01-20 13:40:19 -080027import android.content.Context;
Lucky Zhang3bcea022014-11-25 18:22:14 -080028import android.content.DialogInterface;
Dianne Hackbornabc3dc62010-01-20 13:40:19 -080029import android.content.Intent;
30import android.os.Bundle;
Jim Miller46c7f6d2014-10-13 18:15:17 -070031import android.os.Process;
Jim Millerbbb4afa2010-04-08 19:40:19 -070032import android.preference.Preference;
Jim Millerbbb4afa2010-04-08 19:40:19 -070033import android.preference.PreferenceScreen;
Brian Carlstromd4023b72011-05-25 13:24:20 -070034import android.security.KeyStore;
Jim Miller595982d2015-04-01 16:49:33 -070035import android.hardware.fingerprint.Fingerprint;
36import android.hardware.fingerprint.FingerprintManager;
37import android.hardware.fingerprint.FingerprintManager.RemovalCallback;
rich cannings27d6f8d2013-05-29 14:54:58 -070038import android.util.EventLog;
Lucky Zhang3bcea022014-11-25 18:22:14 -080039import android.util.Log;
Svetoslav52448442014-09-29 18:15:45 -070040import android.view.accessibility.AccessibilityManager;
Jim Millerd16c9b72015-03-24 16:02:59 -070041import android.widget.Toast;
42
Chris Wren8a963ba2015-03-20 10:29:14 -040043import com.android.internal.logging.MetricsLogger;
Gilles Debunne64650542011-08-23 11:01:35 -070044import com.android.internal.widget.LockPatternUtils;
45
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080046public class ChooseLockGeneric extends SettingsActivity {
Jim Miller0698a212014-10-16 19:49:07 -070047 public static final String CONFIRM_CREDENTIALS = "confirm_credentials";
Dianne Hackbornabc3dc62010-01-20 13:40:19 -080048
49 @Override
Jim Miller17e9e192010-12-07 20:41:41 -080050 public Intent getIntent() {
51 Intent modIntent = new Intent(super.getIntent());
Maurice Lam52c75ba2014-11-25 14:06:38 -080052 modIntent.putExtra(EXTRA_SHOW_FRAGMENT, getFragmentClass().getName());
Jim Miller17e9e192010-12-07 20:41:41 -080053 return modIntent;
54 }
Jim Millerbbb4afa2010-04-08 19:40:19 -070055
Amith Yamasania677ee22013-07-26 13:38:41 -070056 @Override
57 protected boolean isValidFragment(String fragmentName) {
58 if (ChooseLockGenericFragment.class.getName().equals(fragmentName)) return true;
59 return false;
60 }
61
Maurice Lam52c75ba2014-11-25 14:06:38 -080062 /* package */ Class<? extends Fragment> getFragmentClass() {
63 return ChooseLockGenericFragment.class;
64 }
65
Amith Yamasani66026772013-09-25 14:05:33 -070066 public static class InternalActivity extends ChooseLockGeneric {
67 }
68
Jim Miller17e9e192010-12-07 20:41:41 -080069 public static class ChooseLockGenericFragment extends SettingsPreferenceFragment {
Jim Miller3fb2fb82015-03-11 20:17:39 -070070 private static final String TAG = "ChooseLockGenericFragment";
Jim Miller17e9e192010-12-07 20:41:41 -080071 private static final int MIN_PASSWORD_LENGTH = 4;
72 private static final String KEY_UNLOCK_SET_OFF = "unlock_set_off";
73 private static final String KEY_UNLOCK_SET_NONE = "unlock_set_none";
74 private static final String KEY_UNLOCK_SET_PIN = "unlock_set_pin";
75 private static final String KEY_UNLOCK_SET_PASSWORD = "unlock_set_password";
76 private static final String KEY_UNLOCK_SET_PATTERN = "unlock_set_pattern";
Jim Miller17e9e192010-12-07 20:41:41 -080077 private static final String PASSWORD_CONFIRMED = "password_confirmed";
Jim Miller47f1cd42012-04-27 18:11:03 -070078 private static final String WAITING_FOR_CONFIRMATION = "waiting_for_confirmation";
Brian Carlstromd4023b72011-05-25 13:24:20 -070079 public static final String MINIMUM_QUALITY_KEY = "minimum_quality";
Jim Miller3fb2fb82015-03-11 20:17:39 -070080 public static final String HIDE_DISABLED_PREFS = "hide_disabled_prefs";
Jim Miller46c7f6d2014-10-13 18:15:17 -070081 public static final String ENCRYPT_REQUESTED_QUALITY = "encrypt_requested_quality";
82 public static final String ENCRYPT_REQUESTED_DISABLED = "encrypt_requested_disabled";
Lucky Zhang3bcea022014-11-25 18:22:14 -080083 public static final String TAG_FRP_WARNING_DIALOG = "frp_warning_dialog";
Jim Millerbbb4afa2010-04-08 19:40:19 -070084
Jim Miller3fb2fb82015-03-11 20:17:39 -070085 private static final int CONFIRM_EXISTING_REQUEST = 100;
86 private static final int ENABLE_ENCRYPTION_REQUEST = 101;
87 private static final int CHOOSE_LOCK_REQUEST = 102;
Danielle Millett80412e72011-10-17 19:21:19 -040088
Jim Miller17e9e192010-12-07 20:41:41 -080089 private ChooseLockSettingsHelper mChooseLockSettingsHelper;
90 private DevicePolicyManager mDPM;
Brian Carlstromd4023b72011-05-25 13:24:20 -070091 private KeyStore mKeyStore;
Andres Morales6609b0c2015-04-12 15:38:25 -070092 private boolean mHasChallenge = false;
93 private long mChallenge;
Jim Miller17e9e192010-12-07 20:41:41 -080094 private boolean mPasswordConfirmed = false;
Jim Miller47f1cd42012-04-27 18:11:03 -070095 private boolean mWaitingForConfirmation = false;
Jim Miller46c7f6d2014-10-13 18:15:17 -070096 private int mEncryptionRequestQuality;
97 private boolean mEncryptionRequestDisabled;
Jim Miller0698a212014-10-16 19:49:07 -070098 private boolean mRequirePassword;
Andres Moralesa0e12362015-04-02 09:00:41 -070099 private String mUserPassword;
Jim Miller0698a212014-10-16 19:49:07 -0700100 private LockPatternUtils mLockPatternUtils;
Jim Miller92186872015-03-04 18:07:32 -0800101 private FingerprintManager mFingerprintManager;
Jim Millerd16c9b72015-03-24 16:02:59 -0700102 private RemovalCallback mRemovalCallback = new RemovalCallback() {
103
104 @Override
105 public void onRemovalSucceeded(Fingerprint fingerprint) {
106 Log.v(TAG, "Fingerprint removed: " + fingerprint.getFingerId());
107 }
108
109 @Override
110 public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString) {
111 Toast.makeText(getActivity(), errString, Toast.LENGTH_SHORT);
112 }
113 };
Jim Millerbbb4afa2010-04-08 19:40:19 -0700114
Jim Miller17e9e192010-12-07 20:41:41 -0800115 @Override
Chris Wren8a963ba2015-03-20 10:29:14 -0400116 protected int getMetricsCategory() {
117 return MetricsLogger.CHOOSE_LOCK_GENERIC;
118 }
119
120 @Override
Jim Miller17e9e192010-12-07 20:41:41 -0800121 public void onCreate(Bundle savedInstanceState) {
122 super.onCreate(savedInstanceState);
123
Jim Miller92186872015-03-04 18:07:32 -0800124 mFingerprintManager =
125 (FingerprintManager) getActivity().getSystemService(Context.FINGERPRINT_SERVICE);
Jim Miller17e9e192010-12-07 20:41:41 -0800126 mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
Brian Carlstromd4023b72011-05-25 13:24:20 -0700127 mKeyStore = KeyStore.getInstance();
Jim Miller17e9e192010-12-07 20:41:41 -0800128 mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this.getActivity());
Jim Miller0698a212014-10-16 19:49:07 -0700129 mLockPatternUtils = new LockPatternUtils(getActivity());
Jim Miller17e9e192010-12-07 20:41:41 -0800130
Danielle Millettc474a882011-09-14 11:42:06 -0400131 // Defaults to needing to confirm credentials
132 final boolean confirmCredentials = getActivity().getIntent()
133 .getBooleanExtra(CONFIRM_CREDENTIALS, true);
Amith Yamasani66026772013-09-25 14:05:33 -0700134 if (getActivity() instanceof ChooseLockGeneric.InternalActivity) {
135 mPasswordConfirmed = !confirmCredentials;
136 }
Danielle Millettc474a882011-09-14 11:42:06 -0400137
Andres Morales6609b0c2015-04-12 15:38:25 -0700138 mHasChallenge = getActivity().getIntent().getBooleanExtra(
139 ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
140 mChallenge = getActivity().getIntent().getLongExtra(
141 ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
142
Jim Miller17e9e192010-12-07 20:41:41 -0800143 if (savedInstanceState != null) {
144 mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
Jim Miller47f1cd42012-04-27 18:11:03 -0700145 mWaitingForConfirmation = savedInstanceState.getBoolean(WAITING_FOR_CONFIRMATION);
Jim Miller46c7f6d2014-10-13 18:15:17 -0700146 mEncryptionRequestQuality = savedInstanceState.getInt(ENCRYPT_REQUESTED_QUALITY);
147 mEncryptionRequestDisabled = savedInstanceState.getBoolean(
148 ENCRYPT_REQUESTED_DISABLED);
Jim Miller17e9e192010-12-07 20:41:41 -0800149 }
150
Jim Miller47f1cd42012-04-27 18:11:03 -0700151 if (mPasswordConfirmed) {
152 updatePreferencesOrFinish();
153 } else if (!mWaitingForConfirmation) {
Andy Stadler6370c872011-01-21 16:25:22 -0800154 ChooseLockSettingsHelper helper =
155 new ChooseLockSettingsHelper(this.getActivity(), this);
Jorim Jaggi8a09b612015-04-06 17:47:18 -0700156 if (!helper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST,
Andres Moralesa0e12362015-04-02 09:00:41 -0700157 getString(R.string.unlock_set_unlock_launch_picker_title), true)) {
Jim Miller17e9e192010-12-07 20:41:41 -0800158 mPasswordConfirmed = true; // no password set, so no need to confirm
159 updatePreferencesOrFinish();
Jim Miller47f1cd42012-04-27 18:11:03 -0700160 } else {
161 mWaitingForConfirmation = true;
Jim Miller17e9e192010-12-07 20:41:41 -0800162 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700163 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700164 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700165
Amith Yamasanic666c652012-10-24 10:27:05 -0700166 @Override
Jim Miller17e9e192010-12-07 20:41:41 -0800167 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
168 Preference preference) {
169 final String key = preference.getKey();
rich cannings27d6f8d2013-05-29 14:54:58 -0700170
Lucky Zhang3bcea022014-11-25 18:22:14 -0800171 if (!isUnlockMethodSecure(key) && mLockPatternUtils.isSecure()) {
172 // Show the disabling FRP warning only when the user is switching from a secure
173 // unlock method to an insecure one
174 showFactoryResetProtectionWarningDialog(key);
175 return true;
Jim Miller17e9e192010-12-07 20:41:41 -0800176 } else {
Lucky Zhang3bcea022014-11-25 18:22:14 -0800177 return setUnlockMethod(key);
Jim Miller17e9e192010-12-07 20:41:41 -0800178 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700179 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700180
Jim Miller46c7f6d2014-10-13 18:15:17 -0700181 /**
182 * If the device has encryption already enabled, then ask the user if they
183 * also want to encrypt the phone with this password.
184 *
185 * @param quality
186 * @param disabled
187 */
Andres Moralesa0e12362015-04-02 09:00:41 -0700188 // TODO: why does this take disabled, its always called with a quality higher than
189 // what makes sense with disabled == true
Jim Miller46c7f6d2014-10-13 18:15:17 -0700190 private void maybeEnableEncryption(int quality, boolean disabled) {
191 if (Process.myUserHandle().isOwner() && LockPatternUtils.isDeviceEncryptionEnabled()) {
192 mEncryptionRequestQuality = quality;
193 mEncryptionRequestDisabled = disabled;
Maurice Lamecd2b7b2014-12-01 10:41:49 -0800194 final Context context = getActivity();
Jim Miller0698a212014-10-16 19:49:07 -0700195 // If accessibility is enabled and the user hasn't seen this dialog before, set the
196 // default state to agree with that which is compatible with accessibility
197 // (password not required).
Maurice Lamecd2b7b2014-12-01 10:41:49 -0800198 final boolean accEn = AccessibilityManager.getInstance(context).isEnabled();
Jim Miller0698a212014-10-16 19:49:07 -0700199 final boolean required = mLockPatternUtils.isCredentialRequiredToDecrypt(!accEn);
Maurice Lamecd2b7b2014-12-01 10:41:49 -0800200 Intent intent = getEncryptionInterstitialIntent(context, quality, required);
Jim Miller46c7f6d2014-10-13 18:15:17 -0700201 startActivityForResult(intent, ENABLE_ENCRYPTION_REQUEST);
202 } else {
Jim Miller0698a212014-10-16 19:49:07 -0700203 mRequirePassword = false; // device encryption not enabled or not device owner.
Jim Miller46c7f6d2014-10-13 18:15:17 -0700204 updateUnlockMethodAndFinish(quality, disabled);
205 }
206 }
207
Jim Miller17e9e192010-12-07 20:41:41 -0800208 @Override
209 public void onActivityResult(int requestCode, int resultCode, Intent data) {
210 super.onActivityResult(requestCode, resultCode, data);
Jim Miller47f1cd42012-04-27 18:11:03 -0700211 mWaitingForConfirmation = false;
Jim Miller17e9e192010-12-07 20:41:41 -0800212 if (requestCode == CONFIRM_EXISTING_REQUEST && resultCode == Activity.RESULT_OK) {
213 mPasswordConfirmed = true;
Andres Moralesa0e12362015-04-02 09:00:41 -0700214 mUserPassword = data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
Jim Miller17e9e192010-12-07 20:41:41 -0800215 updatePreferencesOrFinish();
Jim Miller46c7f6d2014-10-13 18:15:17 -0700216 } else if (requestCode == ENABLE_ENCRYPTION_REQUEST
217 && resultCode == Activity.RESULT_OK) {
Jim Miller0698a212014-10-16 19:49:07 -0700218 mRequirePassword = data.getBooleanExtra(
219 EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
Jim Miller46c7f6d2014-10-13 18:15:17 -0700220 updateUnlockMethodAndFinish(mEncryptionRequestQuality, mEncryptionRequestDisabled);
Maurice Lam9066a5c2015-01-22 18:35:11 -0800221 } else if (requestCode == CHOOSE_LOCK_REQUEST) {
222 getActivity().setResult(resultCode, data);
223 finish();
Jim Miller17e9e192010-12-07 20:41:41 -0800224 } else {
225 getActivity().setResult(Activity.RESULT_CANCELED);
226 finish();
227 }
228 }
229
230 @Override
231 public void onSaveInstanceState(Bundle outState) {
232 super.onSaveInstanceState(outState);
233 // Saved so we don't force user to re-enter their password if configuration changes
234 outState.putBoolean(PASSWORD_CONFIRMED, mPasswordConfirmed);
Jim Miller47f1cd42012-04-27 18:11:03 -0700235 outState.putBoolean(WAITING_FOR_CONFIRMATION, mWaitingForConfirmation);
Jim Miller46c7f6d2014-10-13 18:15:17 -0700236 outState.putInt(ENCRYPT_REQUESTED_QUALITY, mEncryptionRequestQuality);
237 outState.putBoolean(ENCRYPT_REQUESTED_DISABLED, mEncryptionRequestDisabled);
Jim Miller17e9e192010-12-07 20:41:41 -0800238 }
239
240 private void updatePreferencesOrFinish() {
Jim Miller5541a862011-09-02 17:33:53 -0700241 Intent intent = getActivity().getIntent();
242 int quality = intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, -1);
Jim Miller17e9e192010-12-07 20:41:41 -0800243 if (quality == -1) {
Andy Stadler6370c872011-01-21 16:25:22 -0800244 // If caller didn't specify password quality, show UI and allow the user to choose.
Jim Miller5541a862011-09-02 17:33:53 -0700245 quality = intent.getIntExtra(MINIMUM_QUALITY_KEY, -1);
Adrian Roosf7887182015-01-07 20:51:57 +0100246 quality = upgradeQuality(quality);
Jim Miller3fb2fb82015-03-11 20:17:39 -0700247 final boolean hideDisabledPrefs = intent.getBooleanExtra(
248 HIDE_DISABLED_PREFS, false);
Jim Miller17e9e192010-12-07 20:41:41 -0800249 final PreferenceScreen prefScreen = getPreferenceScreen();
250 if (prefScreen != null) {
251 prefScreen.removeAll();
252 }
253 addPreferencesFromResource(R.xml.security_settings_picker);
Jim Miller3fb2fb82015-03-11 20:17:39 -0700254 disableUnusablePreferences(quality, hideDisabledPrefs);
Jason Monk9a64a422015-03-30 11:00:36 -0400255 updateCurrentPreference();
Svetoslav52448442014-09-29 18:15:45 -0700256 updatePreferenceSummaryIfNeeded();
Jim Miller17e9e192010-12-07 20:41:41 -0800257 } else {
258 updateUnlockMethodAndFinish(quality, false);
259 }
260 }
261
Jason Monk9a64a422015-03-30 11:00:36 -0400262 private void updateCurrentPreference() {
263 String currentKey = getKeyForCurrent();
264 Preference preference = findPreference(currentKey);
265 if (preference != null) {
266 preference.setSummary(R.string.current_screen_lock);
267 }
268 }
269
270 private String getKeyForCurrent() {
271 if (mLockPatternUtils.isLockScreenDisabled()) {
272 return KEY_UNLOCK_SET_OFF;
273 }
274 switch (mLockPatternUtils.getKeyguardStoredPasswordQuality()) {
275 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
276 return KEY_UNLOCK_SET_PATTERN;
277 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
278 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
279 return KEY_UNLOCK_SET_PIN;
280 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
281 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
282 return KEY_UNLOCK_SET_PASSWORD;
283 case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
284 return KEY_UNLOCK_SET_NONE;
285 }
286 return null;
287 }
288
Adrian Roosf7887182015-01-07 20:51:57 +0100289 /** increases the quality if necessary */
290 private int upgradeQuality(int quality) {
Brian Carlstromd4023b72011-05-25 13:24:20 -0700291 quality = upgradeQualityForDPM(quality);
Brian Carlstromd4023b72011-05-25 13:24:20 -0700292 quality = upgradeQualityForKeyStore(quality);
Paul Lawrenceb05f39d2014-02-04 10:22:19 -0800293 return quality;
Brian Carlstromd4023b72011-05-25 13:24:20 -0700294 }
295
296 private int upgradeQualityForDPM(int quality) {
297 // Compare min allowed password quality
298 int minQuality = mDPM.getPasswordQuality(null);
299 if (quality < minQuality) {
300 quality = minQuality;
301 }
302 return quality;
303 }
304
Brian Carlstromd4023b72011-05-25 13:24:20 -0700305 private int upgradeQualityForKeyStore(int quality) {
306 if (!mKeyStore.isEmpty()) {
307 if (quality < CredentialStorage.MIN_PASSWORD_QUALITY) {
308 quality = CredentialStorage.MIN_PASSWORD_QUALITY;
Andy Stadler6370c872011-01-21 16:25:22 -0800309 }
310 }
311 return quality;
312 }
313
Jim Miller17e9e192010-12-07 20:41:41 -0800314 /***
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800315 * Disables preferences that are less secure than required quality. The actual
316 * implementation is in disableUnusablePreferenceImpl.
317 *
318 * @param quality the requested quality.
Jim Miller3fb2fb82015-03-11 20:17:39 -0700319 * @param hideDisabledPrefs if false preferences show why they were disabled; otherwise
320 * they're not shown at all.
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800321 */
Jim Miller3fb2fb82015-03-11 20:17:39 -0700322 protected void disableUnusablePreferences(final int quality, boolean hideDisabledPrefs) {
323 disableUnusablePreferencesImpl(quality, hideDisabledPrefs);
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800324 }
325
326 /***
Jim Miller17e9e192010-12-07 20:41:41 -0800327 * Disables preferences that are less secure than required quality.
328 *
329 * @param quality the requested quality.
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800330 * @param hideDisabled whether to hide disable screen lock options.
Jim Miller17e9e192010-12-07 20:41:41 -0800331 */
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800332 protected void disableUnusablePreferencesImpl(final int quality,
Adrian Roosf7887182015-01-07 20:51:57 +0100333 boolean hideDisabled) {
Amith Yamasanicf26bb22011-09-26 10:27:43 -0700334 final PreferenceScreen entries = getPreferenceScreen();
Jim Miller783ea852012-11-01 19:39:21 -0700335
Amith Yamasanicf26bb22011-09-26 10:27:43 -0700336 for (int i = entries.getPreferenceCount() - 1; i >= 0; --i) {
337 Preference pref = entries.getPreference(i);
Jim Miller17e9e192010-12-07 20:41:41 -0800338 if (pref instanceof PreferenceScreen) {
Adrian Roos591dc852015-04-07 16:55:29 +0200339 final String key = pref.getKey();
Jim Miller17e9e192010-12-07 20:41:41 -0800340 boolean enabled = true;
Jim Miller5541a862011-09-02 17:33:53 -0700341 boolean visible = true;
Amith Yamasanicf26bb22011-09-26 10:27:43 -0700342 if (KEY_UNLOCK_SET_OFF.equals(key)) {
Jim Miller17e9e192010-12-07 20:41:41 -0800343 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
344 } else if (KEY_UNLOCK_SET_NONE.equals(key)) {
345 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
346 } else if (KEY_UNLOCK_SET_PATTERN.equals(key)) {
347 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
348 } else if (KEY_UNLOCK_SET_PIN.equals(key)) {
Nicolas Prevot8fd852e2014-01-25 01:02:04 +0000349 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
Jim Miller17e9e192010-12-07 20:41:41 -0800350 } else if (KEY_UNLOCK_SET_PASSWORD.equals(key)) {
351 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
352 }
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800353 if (hideDisabled) {
Adrian Roos591dc852015-04-07 16:55:29 +0200354 visible = enabled;
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800355 }
Adrian Roosf7887182015-01-07 20:51:57 +0100356 if (!visible) {
Amith Yamasanicf26bb22011-09-26 10:27:43 -0700357 entries.removePreference(pref);
Jim Miller5541a862011-09-02 17:33:53 -0700358 } else if (!enabled) {
Jim Miller17e9e192010-12-07 20:41:41 -0800359 pref.setSummary(R.string.unlock_set_unlock_disabled_summary);
360 pref.setEnabled(false);
361 }
362 }
363 }
364 }
365
Svetoslav52448442014-09-29 18:15:45 -0700366 private void updatePreferenceSummaryIfNeeded() {
Svetoslav40ca78f2014-10-17 14:37:02 -0700367 if (LockPatternUtils.isDeviceEncrypted()) {
368 return;
369 }
370
Svetoslav52448442014-09-29 18:15:45 -0700371 if (AccessibilityManager.getInstance(getActivity()).getEnabledAccessibilityServiceList(
372 AccessibilityServiceInfo.FEEDBACK_ALL_MASK).isEmpty()) {
373 return;
374 }
375
376 CharSequence summary = getString(R.string.secure_lock_encryption_warning);
377
378 PreferenceScreen screen = getPreferenceScreen();
379 final int preferenceCount = screen.getPreferenceCount();
380 for (int i = 0; i < preferenceCount; i++) {
381 Preference preference = screen.getPreference(i);
382 switch (preference.getKey()) {
383 case KEY_UNLOCK_SET_PATTERN:
384 case KEY_UNLOCK_SET_PIN:
385 case KEY_UNLOCK_SET_PASSWORD: {
386 preference.setSummary(summary);
387 } break;
388 }
389 }
390 }
391
Maurice Lam6b19fa92014-11-25 19:25:56 -0800392 protected Intent getLockPasswordIntent(Context context, int quality,
Adrian Roosf7887182015-01-07 20:51:57 +0100393 int minLength, final int maxLength,
Maurice Lam6b19fa92014-11-25 19:25:56 -0800394 boolean requirePasswordToDecrypt, boolean confirmCredentials) {
Adrian Roosf7887182015-01-07 20:51:57 +0100395 return ChooseLockPassword.createIntent(context, quality, minLength,
Maurice Lam6b19fa92014-11-25 19:25:56 -0800396 maxLength, requirePasswordToDecrypt, confirmCredentials);
397 }
398
Andres Morales6609b0c2015-04-12 15:38:25 -0700399 protected Intent getLockPasswordIntent(Context context, int quality,
400 int minLength, final int maxLength,
401 boolean requirePasswordToDecrypt, long challenge) {
402 return ChooseLockPassword.createIntent(context, quality, minLength,
403 maxLength, requirePasswordToDecrypt, challenge);
404 }
405
Maurice Lam38596432015-04-16 18:11:42 -0700406 protected Intent getLockPasswordIntent(Context context, int quality, int minLength,
Andres Moralesa0e12362015-04-02 09:00:41 -0700407 final int maxLength, boolean requirePasswordToDecrypt, String password) {
408 return ChooseLockPassword.createIntent(context, quality, minLength, maxLength,
409 requirePasswordToDecrypt, password);
410 }
411
Adrian Roosf7887182015-01-07 20:51:57 +0100412 protected Intent getLockPatternIntent(Context context, final boolean requirePassword,
413 final boolean confirmCredentials) {
414 return ChooseLockPattern.createIntent(context, requirePassword,
Maurice Lam6b19fa92014-11-25 19:25:56 -0800415 confirmCredentials);
416 }
417
Andres Morales6609b0c2015-04-12 15:38:25 -0700418 protected Intent getLockPatternIntent(Context context, final boolean requirePassword,
419 long challenge) {
420 return ChooseLockPattern.createIntent(context, requirePassword, challenge);
421 }
422
Maurice Lam38596432015-04-16 18:11:42 -0700423 protected Intent getLockPatternIntent(Context context, final boolean requirePassword,
Andres Moralesa0e12362015-04-02 09:00:41 -0700424 final String pattern) {
425 return ChooseLockPattern.createIntent(context, requirePassword, pattern);
426 }
427
Maurice Lamecd2b7b2014-12-01 10:41:49 -0800428 protected Intent getEncryptionInterstitialIntent(Context context, int quality,
429 boolean required) {
430 return EncryptionInterstitial.createStartIntent(context, quality, required);
431 }
432
Jim Miller5541a862011-09-02 17:33:53 -0700433 /**
Jim Miller17e9e192010-12-07 20:41:41 -0800434 * Invokes an activity to change the user's pattern, password or PIN based on given quality
435 * and minimum quality specified by DevicePolicyManager. If quality is
436 * {@link DevicePolicyManager#PASSWORD_QUALITY_UNSPECIFIED}, password is cleared.
437 *
Andy Stadler6370c872011-01-21 16:25:22 -0800438 * @param quality the desired quality. Ignored if DevicePolicyManager requires more security
Jim Miller17e9e192010-12-07 20:41:41 -0800439 * @param disabled whether or not to show LockScreen at all. Only meaningful when quality is
440 * {@link DevicePolicyManager#PASSWORD_QUALITY_UNSPECIFIED}
441 */
442 void updateUnlockMethodAndFinish(int quality, boolean disabled) {
Andy Stadler6370c872011-01-21 16:25:22 -0800443 // Sanity check. We should never get here without confirming user's existing password.
Jim Miller17e9e192010-12-07 20:41:41 -0800444 if (!mPasswordConfirmed) {
Andy Stadler6370c872011-01-21 16:25:22 -0800445 throw new IllegalStateException("Tried to update password without confirming it");
Jim Miller17e9e192010-12-07 20:41:41 -0800446 }
447
Adrian Roosf7887182015-01-07 20:51:57 +0100448 quality = upgradeQuality(quality);
Steven Rossc620ba42011-09-28 15:43:41 -0400449
Maurice Lam6b19fa92014-11-25 19:25:56 -0800450 final Context context = getActivity();
Jim Miller17e9e192010-12-07 20:41:41 -0800451 if (quality >= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) {
452 int minLength = mDPM.getPasswordMinimumLength(null);
453 if (minLength < MIN_PASSWORD_LENGTH) {
454 minLength = MIN_PASSWORD_LENGTH;
455 }
456 final int maxLength = mDPM.getPasswordMaximumLength(quality);
Andres Morales6609b0c2015-04-12 15:38:25 -0700457 Intent intent;
458 if (mHasChallenge) {
459 intent = getLockPasswordIntent(context, quality, minLength,
460 maxLength, mRequirePassword, mChallenge);
461 } else {
462 intent = getLockPasswordIntent(context, quality, minLength,
Andres Moralesa0e12362015-04-02 09:00:41 -0700463 maxLength, mRequirePassword, mUserPassword);
Andres Morales6609b0c2015-04-12 15:38:25 -0700464 }
Maurice Lam9066a5c2015-01-22 18:35:11 -0800465 startActivityForResult(intent, CHOOSE_LOCK_REQUEST);
Adrian Roosf7887182015-01-07 20:51:57 +0100466 } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
Andres Morales6609b0c2015-04-12 15:38:25 -0700467 Intent intent;
468 if (mHasChallenge) {
469 intent = getLockPatternIntent(context, mRequirePassword,
470 mChallenge);
471 } else {
472 intent = getLockPatternIntent(context, mRequirePassword,
Andres Moralesa0e12362015-04-02 09:00:41 -0700473 mUserPassword);
Andres Morales6609b0c2015-04-12 15:38:25 -0700474 }
Maurice Lam9066a5c2015-01-22 18:35:11 -0800475 startActivityForResult(intent, CHOOSE_LOCK_REQUEST);
Jim Miller17e9e192010-12-07 20:41:41 -0800476 } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
Adrian Roosf7887182015-01-07 20:51:57 +0100477 mChooseLockSettingsHelper.utils().clearLock();
Jim Miller17e9e192010-12-07 20:41:41 -0800478 mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled);
Jim Miller92186872015-03-04 18:07:32 -0800479 removeAllFingerprintTemplates();
Jim Miller17e9e192010-12-07 20:41:41 -0800480 getActivity().setResult(Activity.RESULT_OK);
Amith Yamasanic666c652012-10-24 10:27:05 -0700481 finish();
482 } else {
Jim Miller92186872015-03-04 18:07:32 -0800483 removeAllFingerprintTemplates();
Amith Yamasanic666c652012-10-24 10:27:05 -0700484 finish();
Jim Miller17e9e192010-12-07 20:41:41 -0800485 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700486 }
Amith Yamasanib0b37ae2012-04-23 15:35:36 -0700487
Jim Miller92186872015-03-04 18:07:32 -0800488 private void removeAllFingerprintTemplates() {
Jim Millerd52b5772015-03-12 10:33:53 -0700489 if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) {
Jim Millerd16c9b72015-03-24 16:02:59 -0700490 mFingerprintManager.remove(new Fingerprint(null, 0, 0, 0), mRemovalCallback);
Jim Miller92186872015-03-04 18:07:32 -0800491 }
492 }
493
494 @Override
495 public void onDestroy() {
496 super.onDestroy();
Jim Miller92186872015-03-04 18:07:32 -0800497 }
498
Amith Yamasanib0b37ae2012-04-23 15:35:36 -0700499 @Override
500 protected int getHelpResource() {
501 return R.string.help_url_choose_lockscreen;
502 }
503
Lucky Zhang3bcea022014-11-25 18:22:14 -0800504 private int getResIdForFactoryResetProtectionWarningTitle() {
505 switch (mLockPatternUtils.getKeyguardStoredPasswordQuality()) {
506 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
507 return R.string.unlock_disable_lock_pattern_summary;
508 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
509 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
510 return R.string.unlock_disable_lock_pin_summary;
511 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
512 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
513 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
514 return R.string.unlock_disable_lock_password_summary;
515 default:
516 return R.string.unlock_disable_lock_unknown_summary;
517 }
518 }
519
520 private boolean isUnlockMethodSecure(String unlockMethod) {
521 return !(KEY_UNLOCK_SET_OFF.equals(unlockMethod) ||
522 KEY_UNLOCK_SET_NONE.equals(unlockMethod));
523 }
524
525 private boolean setUnlockMethod(String unlockMethod) {
526 EventLog.writeEvent(EventLogTags.LOCK_SCREEN_TYPE, unlockMethod);
527
528 if (KEY_UNLOCK_SET_OFF.equals(unlockMethod)) {
529 updateUnlockMethodAndFinish(
530 DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, true /* disabled */ );
531 } else if (KEY_UNLOCK_SET_NONE.equals(unlockMethod)) {
532 updateUnlockMethodAndFinish(
533 DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, false /* disabled */ );
Lucky Zhang3bcea022014-11-25 18:22:14 -0800534 } else if (KEY_UNLOCK_SET_PATTERN.equals(unlockMethod)) {
535 maybeEnableEncryption(
536 DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, false);
537 } else if (KEY_UNLOCK_SET_PIN.equals(unlockMethod)) {
538 maybeEnableEncryption(
539 DevicePolicyManager.PASSWORD_QUALITY_NUMERIC, false);
540 } else if (KEY_UNLOCK_SET_PASSWORD.equals(unlockMethod)) {
541 maybeEnableEncryption(
542 DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC, false);
543 } else {
544 Log.e(TAG, "Encountered unknown unlock method to set: " + unlockMethod);
545 return false;
546 }
547 return true;
548 }
549
550 private void showFactoryResetProtectionWarningDialog(String unlockMethodToSet) {
551 int title = getResIdForFactoryResetProtectionWarningTitle();
552 FactoryResetProtectionWarningDialog dialog =
553 FactoryResetProtectionWarningDialog.newInstance(title, unlockMethodToSet);
554 dialog.show(getChildFragmentManager(), TAG_FRP_WARNING_DIALOG);
555 }
556
557 public static class FactoryResetProtectionWarningDialog extends DialogFragment {
558
559 private static final String ARG_TITLE_RES = "titleRes";
560 private static final String ARG_UNLOCK_METHOD_TO_SET = "unlockMethodToSet";
561
562 public static FactoryResetProtectionWarningDialog newInstance(int title,
563 String unlockMethodToSet) {
564 FactoryResetProtectionWarningDialog frag =
565 new FactoryResetProtectionWarningDialog();
566 Bundle args = new Bundle();
567 args.putInt(ARG_TITLE_RES, title);
568 args.putString(ARG_UNLOCK_METHOD_TO_SET, unlockMethodToSet);
569 frag.setArguments(args);
570 return frag;
571 }
572
573 @Override
574 public void show(FragmentManager manager, String tag) {
575 if (manager.findFragmentByTag(tag) == null) {
576 // Prevent opening multiple dialogs if tapped on button quickly
577 super.show(manager, tag);
578 }
579 }
580
581 @Override
582 public Dialog onCreateDialog(Bundle savedInstanceState) {
583 final Bundle args = getArguments();
584
585 return new AlertDialog.Builder(getActivity())
586 .setTitle(args.getInt(ARG_TITLE_RES))
587 .setMessage(R.string.unlock_disable_frp_warning_content)
588 .setPositiveButton(R.string.okay,
589 new DialogInterface.OnClickListener() {
590 @Override
591 public void onClick(DialogInterface dialog, int whichButton) {
592 ((ChooseLockGenericFragment) getParentFragment())
593 .setUnlockMethod(
594 args.getString(ARG_UNLOCK_METHOD_TO_SET));
595 }
596 }
597 )
598 .setNegativeButton(R.string.cancel,
599 new DialogInterface.OnClickListener() {
600 @Override
601 public void onClick(DialogInterface dialog, int whichButton) {
602 dismiss();
603 }
604 }
605 )
606 .create();
607 }
608 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700609 }
Dianne Hackbornabc3dc62010-01-20 13:40:19 -0800610}