blob: 70ef4d9f97b92406d7bd4651b5fa22327e5b7d8c [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;
Adrian Roos54375882015-04-16 17:11:22 -070032import android.os.UserHandle;
Jim Millerbbb4afa2010-04-08 19:40:19 -070033import android.preference.Preference;
Jim Millerbbb4afa2010-04-08 19:40:19 -070034import android.preference.PreferenceScreen;
Brian Carlstromd4023b72011-05-25 13:24:20 -070035import android.security.KeyStore;
Jim Miller595982d2015-04-01 16:49:33 -070036import android.hardware.fingerprint.Fingerprint;
37import android.hardware.fingerprint.FingerprintManager;
38import android.hardware.fingerprint.FingerprintManager.RemovalCallback;
rich cannings27d6f8d2013-05-29 14:54:58 -070039import android.util.EventLog;
Lucky Zhang3bcea022014-11-25 18:22:14 -080040import android.util.Log;
Svetoslav52448442014-09-29 18:15:45 -070041import android.view.accessibility.AccessibilityManager;
Jim Millerd16c9b72015-03-24 16:02:59 -070042import android.widget.Toast;
43
Chris Wren8a963ba2015-03-20 10:29:14 -040044import com.android.internal.logging.MetricsLogger;
Gilles Debunne64650542011-08-23 11:01:35 -070045import com.android.internal.widget.LockPatternUtils;
46
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080047public class ChooseLockGeneric extends SettingsActivity {
Jim Miller0698a212014-10-16 19:49:07 -070048 public static final String CONFIRM_CREDENTIALS = "confirm_credentials";
Dianne Hackbornabc3dc62010-01-20 13:40:19 -080049
50 @Override
Jim Miller17e9e192010-12-07 20:41:41 -080051 public Intent getIntent() {
52 Intent modIntent = new Intent(super.getIntent());
Maurice Lam52c75ba2014-11-25 14:06:38 -080053 modIntent.putExtra(EXTRA_SHOW_FRAGMENT, getFragmentClass().getName());
Jim Miller17e9e192010-12-07 20:41:41 -080054 return modIntent;
55 }
Jim Millerbbb4afa2010-04-08 19:40:19 -070056
Amith Yamasania677ee22013-07-26 13:38:41 -070057 @Override
58 protected boolean isValidFragment(String fragmentName) {
59 if (ChooseLockGenericFragment.class.getName().equals(fragmentName)) return true;
60 return false;
61 }
62
Maurice Lam52c75ba2014-11-25 14:06:38 -080063 /* package */ Class<? extends Fragment> getFragmentClass() {
64 return ChooseLockGenericFragment.class;
65 }
66
Amith Yamasani66026772013-09-25 14:05:33 -070067 public static class InternalActivity extends ChooseLockGeneric {
68 }
69
Jim Miller17e9e192010-12-07 20:41:41 -080070 public static class ChooseLockGenericFragment extends SettingsPreferenceFragment {
Jim Miller3fb2fb82015-03-11 20:17:39 -070071 private static final String TAG = "ChooseLockGenericFragment";
Jim Miller17e9e192010-12-07 20:41:41 -080072 private static final int MIN_PASSWORD_LENGTH = 4;
73 private static final String KEY_UNLOCK_SET_OFF = "unlock_set_off";
74 private static final String KEY_UNLOCK_SET_NONE = "unlock_set_none";
75 private static final String KEY_UNLOCK_SET_PIN = "unlock_set_pin";
76 private static final String KEY_UNLOCK_SET_PASSWORD = "unlock_set_password";
77 private static final String KEY_UNLOCK_SET_PATTERN = "unlock_set_pattern";
Jim Miller17e9e192010-12-07 20:41:41 -080078 private static final String PASSWORD_CONFIRMED = "password_confirmed";
Jim Miller47f1cd42012-04-27 18:11:03 -070079 private static final String WAITING_FOR_CONFIRMATION = "waiting_for_confirmation";
Brian Carlstromd4023b72011-05-25 13:24:20 -070080 public static final String MINIMUM_QUALITY_KEY = "minimum_quality";
Jim Miller3fb2fb82015-03-11 20:17:39 -070081 public static final String HIDE_DISABLED_PREFS = "hide_disabled_prefs";
Jim Miller46c7f6d2014-10-13 18:15:17 -070082 public static final String ENCRYPT_REQUESTED_QUALITY = "encrypt_requested_quality";
83 public static final String ENCRYPT_REQUESTED_DISABLED = "encrypt_requested_disabled";
Lucky Zhang3bcea022014-11-25 18:22:14 -080084 public static final String TAG_FRP_WARNING_DIALOG = "frp_warning_dialog";
Jim Millerbbb4afa2010-04-08 19:40:19 -070085
Jim Miller3fb2fb82015-03-11 20:17:39 -070086 private static final int CONFIRM_EXISTING_REQUEST = 100;
87 private static final int ENABLE_ENCRYPTION_REQUEST = 101;
88 private static final int CHOOSE_LOCK_REQUEST = 102;
Danielle Millett80412e72011-10-17 19:21:19 -040089
Jim Miller17e9e192010-12-07 20:41:41 -080090 private ChooseLockSettingsHelper mChooseLockSettingsHelper;
91 private DevicePolicyManager mDPM;
Brian Carlstromd4023b72011-05-25 13:24:20 -070092 private KeyStore mKeyStore;
Andres Morales6609b0c2015-04-12 15:38:25 -070093 private boolean mHasChallenge = false;
94 private long mChallenge;
Jim Miller17e9e192010-12-07 20:41:41 -080095 private boolean mPasswordConfirmed = false;
Jim Miller47f1cd42012-04-27 18:11:03 -070096 private boolean mWaitingForConfirmation = false;
Jim Miller46c7f6d2014-10-13 18:15:17 -070097 private int mEncryptionRequestQuality;
98 private boolean mEncryptionRequestDisabled;
Jim Miller0698a212014-10-16 19:49:07 -070099 private boolean mRequirePassword;
Maurice Lamc0e78792015-07-20 14:49:29 -0700100 private boolean mForFingerprint = false;
Andres Moralesa0e12362015-04-02 09:00:41 -0700101 private String mUserPassword;
Jim Miller0698a212014-10-16 19:49:07 -0700102 private LockPatternUtils mLockPatternUtils;
Jim Miller92186872015-03-04 18:07:32 -0800103 private FingerprintManager mFingerprintManager;
Jim Millerd16c9b72015-03-24 16:02:59 -0700104 private RemovalCallback mRemovalCallback = new RemovalCallback() {
105
106 @Override
107 public void onRemovalSucceeded(Fingerprint fingerprint) {
108 Log.v(TAG, "Fingerprint removed: " + fingerprint.getFingerId());
109 }
110
111 @Override
112 public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString) {
113 Toast.makeText(getActivity(), errString, Toast.LENGTH_SHORT);
114 }
115 };
Jim Millerbbb4afa2010-04-08 19:40:19 -0700116
Jim Miller17e9e192010-12-07 20:41:41 -0800117 @Override
Chris Wren8a963ba2015-03-20 10:29:14 -0400118 protected int getMetricsCategory() {
119 return MetricsLogger.CHOOSE_LOCK_GENERIC;
120 }
121
122 @Override
Jim Miller17e9e192010-12-07 20:41:41 -0800123 public void onCreate(Bundle savedInstanceState) {
124 super.onCreate(savedInstanceState);
125
Jim Miller92186872015-03-04 18:07:32 -0800126 mFingerprintManager =
127 (FingerprintManager) getActivity().getSystemService(Context.FINGERPRINT_SERVICE);
Jim Miller17e9e192010-12-07 20:41:41 -0800128 mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
Brian Carlstromd4023b72011-05-25 13:24:20 -0700129 mKeyStore = KeyStore.getInstance();
Jim Miller17e9e192010-12-07 20:41:41 -0800130 mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this.getActivity());
Jim Miller0698a212014-10-16 19:49:07 -0700131 mLockPatternUtils = new LockPatternUtils(getActivity());
Jim Miller17e9e192010-12-07 20:41:41 -0800132
Danielle Millettc474a882011-09-14 11:42:06 -0400133 // Defaults to needing to confirm credentials
134 final boolean confirmCredentials = getActivity().getIntent()
135 .getBooleanExtra(CONFIRM_CREDENTIALS, true);
Amith Yamasani66026772013-09-25 14:05:33 -0700136 if (getActivity() instanceof ChooseLockGeneric.InternalActivity) {
137 mPasswordConfirmed = !confirmCredentials;
138 }
Danielle Millettc474a882011-09-14 11:42:06 -0400139
Andres Morales6609b0c2015-04-12 15:38:25 -0700140 mHasChallenge = getActivity().getIntent().getBooleanExtra(
141 ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
142 mChallenge = getActivity().getIntent().getLongExtra(
143 ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
Maurice Lamc0e78792015-07-20 14:49:29 -0700144 mForFingerprint = getActivity().getIntent().getBooleanExtra(
145 ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
Andres Morales6609b0c2015-04-12 15:38:25 -0700146
Jim Miller17e9e192010-12-07 20:41:41 -0800147 if (savedInstanceState != null) {
148 mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
Jim Miller47f1cd42012-04-27 18:11:03 -0700149 mWaitingForConfirmation = savedInstanceState.getBoolean(WAITING_FOR_CONFIRMATION);
Jim Miller46c7f6d2014-10-13 18:15:17 -0700150 mEncryptionRequestQuality = savedInstanceState.getInt(ENCRYPT_REQUESTED_QUALITY);
151 mEncryptionRequestDisabled = savedInstanceState.getBoolean(
152 ENCRYPT_REQUESTED_DISABLED);
Jim Miller17e9e192010-12-07 20:41:41 -0800153 }
154
Jim Miller47f1cd42012-04-27 18:11:03 -0700155 if (mPasswordConfirmed) {
156 updatePreferencesOrFinish();
157 } else if (!mWaitingForConfirmation) {
Andy Stadler6370c872011-01-21 16:25:22 -0800158 ChooseLockSettingsHelper helper =
159 new ChooseLockSettingsHelper(this.getActivity(), this);
Jorim Jaggi8a09b612015-04-06 17:47:18 -0700160 if (!helper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST,
Andres Moralesa0e12362015-04-02 09:00:41 -0700161 getString(R.string.unlock_set_unlock_launch_picker_title), true)) {
Jim Miller17e9e192010-12-07 20:41:41 -0800162 mPasswordConfirmed = true; // no password set, so no need to confirm
163 updatePreferencesOrFinish();
Jim Miller47f1cd42012-04-27 18:11:03 -0700164 } else {
165 mWaitingForConfirmation = true;
Jim Miller17e9e192010-12-07 20:41:41 -0800166 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700167 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700168 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700169
Amith Yamasanic666c652012-10-24 10:27:05 -0700170 @Override
Jim Miller17e9e192010-12-07 20:41:41 -0800171 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
172 Preference preference) {
173 final String key = preference.getKey();
rich cannings27d6f8d2013-05-29 14:54:58 -0700174
Adrian Roos54375882015-04-16 17:11:22 -0700175 if (!isUnlockMethodSecure(key) && mLockPatternUtils.isSecure(UserHandle.myUserId())) {
Lucky Zhang3bcea022014-11-25 18:22:14 -0800176 // Show the disabling FRP warning only when the user is switching from a secure
177 // unlock method to an insecure one
178 showFactoryResetProtectionWarningDialog(key);
179 return true;
Jim Miller17e9e192010-12-07 20:41:41 -0800180 } else {
Lucky Zhang3bcea022014-11-25 18:22:14 -0800181 return setUnlockMethod(key);
Jim Miller17e9e192010-12-07 20:41:41 -0800182 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700183 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700184
Jim Miller46c7f6d2014-10-13 18:15:17 -0700185 /**
186 * If the device has encryption already enabled, then ask the user if they
187 * also want to encrypt the phone with this password.
188 *
189 * @param quality
190 * @param disabled
191 */
Andres Moralesa0e12362015-04-02 09:00:41 -0700192 // TODO: why does this take disabled, its always called with a quality higher than
193 // what makes sense with disabled == true
Jim Miller46c7f6d2014-10-13 18:15:17 -0700194 private void maybeEnableEncryption(int quality, boolean disabled) {
Andrei Kapishnikov146fc112015-04-09 11:08:16 -0400195 DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
196 if (Process.myUserHandle().isOwner() && LockPatternUtils.isDeviceEncryptionEnabled()
197 && !dpm.getDoNotAskCredentialsOnBoot()) {
Jim Miller46c7f6d2014-10-13 18:15:17 -0700198 mEncryptionRequestQuality = quality;
199 mEncryptionRequestDisabled = disabled;
Maurice Lamecd2b7b2014-12-01 10:41:49 -0800200 final Context context = getActivity();
Jim Miller0698a212014-10-16 19:49:07 -0700201 // If accessibility is enabled and the user hasn't seen this dialog before, set the
202 // default state to agree with that which is compatible with accessibility
203 // (password not required).
Maurice Lamecd2b7b2014-12-01 10:41:49 -0800204 final boolean accEn = AccessibilityManager.getInstance(context).isEnabled();
Jim Miller0698a212014-10-16 19:49:07 -0700205 final boolean required = mLockPatternUtils.isCredentialRequiredToDecrypt(!accEn);
Maurice Lamecd2b7b2014-12-01 10:41:49 -0800206 Intent intent = getEncryptionInterstitialIntent(context, quality, required);
Maurice Lamc0e78792015-07-20 14:49:29 -0700207 intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT,
208 mForFingerprint);
Jim Miller46c7f6d2014-10-13 18:15:17 -0700209 startActivityForResult(intent, ENABLE_ENCRYPTION_REQUEST);
210 } else {
Jim Miller0698a212014-10-16 19:49:07 -0700211 mRequirePassword = false; // device encryption not enabled or not device owner.
Jim Miller46c7f6d2014-10-13 18:15:17 -0700212 updateUnlockMethodAndFinish(quality, disabled);
213 }
214 }
215
Jim Miller17e9e192010-12-07 20:41:41 -0800216 @Override
217 public void onActivityResult(int requestCode, int resultCode, Intent data) {
218 super.onActivityResult(requestCode, resultCode, data);
Jim Miller47f1cd42012-04-27 18:11:03 -0700219 mWaitingForConfirmation = false;
Jim Miller17e9e192010-12-07 20:41:41 -0800220 if (requestCode == CONFIRM_EXISTING_REQUEST && resultCode == Activity.RESULT_OK) {
221 mPasswordConfirmed = true;
Andres Moralesa0e12362015-04-02 09:00:41 -0700222 mUserPassword = data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
Jim Miller17e9e192010-12-07 20:41:41 -0800223 updatePreferencesOrFinish();
Jim Miller46c7f6d2014-10-13 18:15:17 -0700224 } else if (requestCode == ENABLE_ENCRYPTION_REQUEST
225 && resultCode == Activity.RESULT_OK) {
Jim Miller0698a212014-10-16 19:49:07 -0700226 mRequirePassword = data.getBooleanExtra(
227 EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
Jim Miller46c7f6d2014-10-13 18:15:17 -0700228 updateUnlockMethodAndFinish(mEncryptionRequestQuality, mEncryptionRequestDisabled);
Maurice Lam9066a5c2015-01-22 18:35:11 -0800229 } else if (requestCode == CHOOSE_LOCK_REQUEST) {
230 getActivity().setResult(resultCode, data);
231 finish();
Jim Miller17e9e192010-12-07 20:41:41 -0800232 } else {
233 getActivity().setResult(Activity.RESULT_CANCELED);
234 finish();
235 }
236 }
237
238 @Override
239 public void onSaveInstanceState(Bundle outState) {
240 super.onSaveInstanceState(outState);
241 // Saved so we don't force user to re-enter their password if configuration changes
242 outState.putBoolean(PASSWORD_CONFIRMED, mPasswordConfirmed);
Jim Miller47f1cd42012-04-27 18:11:03 -0700243 outState.putBoolean(WAITING_FOR_CONFIRMATION, mWaitingForConfirmation);
Jim Miller46c7f6d2014-10-13 18:15:17 -0700244 outState.putInt(ENCRYPT_REQUESTED_QUALITY, mEncryptionRequestQuality);
245 outState.putBoolean(ENCRYPT_REQUESTED_DISABLED, mEncryptionRequestDisabled);
Jim Miller17e9e192010-12-07 20:41:41 -0800246 }
247
248 private void updatePreferencesOrFinish() {
Jim Miller5541a862011-09-02 17:33:53 -0700249 Intent intent = getActivity().getIntent();
250 int quality = intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, -1);
Jim Miller17e9e192010-12-07 20:41:41 -0800251 if (quality == -1) {
Andy Stadler6370c872011-01-21 16:25:22 -0800252 // If caller didn't specify password quality, show UI and allow the user to choose.
Jim Miller5541a862011-09-02 17:33:53 -0700253 quality = intent.getIntExtra(MINIMUM_QUALITY_KEY, -1);
Adrian Roosf7887182015-01-07 20:51:57 +0100254 quality = upgradeQuality(quality);
Jim Miller3fb2fb82015-03-11 20:17:39 -0700255 final boolean hideDisabledPrefs = intent.getBooleanExtra(
256 HIDE_DISABLED_PREFS, false);
Jim Miller17e9e192010-12-07 20:41:41 -0800257 final PreferenceScreen prefScreen = getPreferenceScreen();
258 if (prefScreen != null) {
259 prefScreen.removeAll();
260 }
261 addPreferencesFromResource(R.xml.security_settings_picker);
Jim Miller3fb2fb82015-03-11 20:17:39 -0700262 disableUnusablePreferences(quality, hideDisabledPrefs);
Jason Monk9a64a422015-03-30 11:00:36 -0400263 updateCurrentPreference();
Svetoslav52448442014-09-29 18:15:45 -0700264 updatePreferenceSummaryIfNeeded();
Jim Miller17e9e192010-12-07 20:41:41 -0800265 } else {
266 updateUnlockMethodAndFinish(quality, false);
267 }
268 }
269
Jason Monk9a64a422015-03-30 11:00:36 -0400270 private void updateCurrentPreference() {
271 String currentKey = getKeyForCurrent();
272 Preference preference = findPreference(currentKey);
273 if (preference != null) {
274 preference.setSummary(R.string.current_screen_lock);
275 }
276 }
277
278 private String getKeyForCurrent() {
Adrian Roos54375882015-04-16 17:11:22 -0700279 if (mLockPatternUtils.isLockScreenDisabled(UserHandle.myUserId())) {
Jason Monk9a64a422015-03-30 11:00:36 -0400280 return KEY_UNLOCK_SET_OFF;
281 }
Adrian Roos54375882015-04-16 17:11:22 -0700282 switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(UserHandle.myUserId())) {
Jason Monk9a64a422015-03-30 11:00:36 -0400283 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
284 return KEY_UNLOCK_SET_PATTERN;
285 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
286 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
287 return KEY_UNLOCK_SET_PIN;
288 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
289 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
290 return KEY_UNLOCK_SET_PASSWORD;
291 case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
292 return KEY_UNLOCK_SET_NONE;
293 }
294 return null;
295 }
296
Adrian Roosf7887182015-01-07 20:51:57 +0100297 /** increases the quality if necessary */
298 private int upgradeQuality(int quality) {
Brian Carlstromd4023b72011-05-25 13:24:20 -0700299 quality = upgradeQualityForDPM(quality);
Paul Lawrenceb05f39d2014-02-04 10:22:19 -0800300 return quality;
Brian Carlstromd4023b72011-05-25 13:24:20 -0700301 }
302
303 private int upgradeQualityForDPM(int quality) {
304 // Compare min allowed password quality
305 int minQuality = mDPM.getPasswordQuality(null);
306 if (quality < minQuality) {
307 quality = minQuality;
308 }
309 return quality;
310 }
311
Jim Miller17e9e192010-12-07 20:41:41 -0800312 /***
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800313 * Disables preferences that are less secure than required quality. The actual
314 * implementation is in disableUnusablePreferenceImpl.
315 *
316 * @param quality the requested quality.
Jim Miller3fb2fb82015-03-11 20:17:39 -0700317 * @param hideDisabledPrefs if false preferences show why they were disabled; otherwise
318 * they're not shown at all.
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800319 */
Jim Miller3fb2fb82015-03-11 20:17:39 -0700320 protected void disableUnusablePreferences(final int quality, boolean hideDisabledPrefs) {
321 disableUnusablePreferencesImpl(quality, hideDisabledPrefs);
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800322 }
323
324 /***
Jim Miller17e9e192010-12-07 20:41:41 -0800325 * Disables preferences that are less secure than required quality.
326 *
327 * @param quality the requested quality.
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800328 * @param hideDisabled whether to hide disable screen lock options.
Jim Miller17e9e192010-12-07 20:41:41 -0800329 */
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800330 protected void disableUnusablePreferencesImpl(final int quality,
Adrian Roosf7887182015-01-07 20:51:57 +0100331 boolean hideDisabled) {
Amith Yamasanicf26bb22011-09-26 10:27:43 -0700332 final PreferenceScreen entries = getPreferenceScreen();
Jim Miller783ea852012-11-01 19:39:21 -0700333
Amith Yamasanicf26bb22011-09-26 10:27:43 -0700334 for (int i = entries.getPreferenceCount() - 1; i >= 0; --i) {
335 Preference pref = entries.getPreference(i);
Jim Miller17e9e192010-12-07 20:41:41 -0800336 if (pref instanceof PreferenceScreen) {
Adrian Roos591dc852015-04-07 16:55:29 +0200337 final String key = pref.getKey();
Jim Miller17e9e192010-12-07 20:41:41 -0800338 boolean enabled = true;
Jim Miller5541a862011-09-02 17:33:53 -0700339 boolean visible = true;
Amith Yamasanicf26bb22011-09-26 10:27:43 -0700340 if (KEY_UNLOCK_SET_OFF.equals(key)) {
Jim Miller17e9e192010-12-07 20:41:41 -0800341 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
342 } else if (KEY_UNLOCK_SET_NONE.equals(key)) {
343 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
344 } else if (KEY_UNLOCK_SET_PATTERN.equals(key)) {
345 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
346 } else if (KEY_UNLOCK_SET_PIN.equals(key)) {
Nicolas Prevot8fd852e2014-01-25 01:02:04 +0000347 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
Jim Miller17e9e192010-12-07 20:41:41 -0800348 } else if (KEY_UNLOCK_SET_PASSWORD.equals(key)) {
349 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
350 }
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800351 if (hideDisabled) {
Adrian Roos591dc852015-04-07 16:55:29 +0200352 visible = enabled;
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800353 }
Adrian Roosf7887182015-01-07 20:51:57 +0100354 if (!visible) {
Amith Yamasanicf26bb22011-09-26 10:27:43 -0700355 entries.removePreference(pref);
Jim Miller5541a862011-09-02 17:33:53 -0700356 } else if (!enabled) {
Jim Miller17e9e192010-12-07 20:41:41 -0800357 pref.setSummary(R.string.unlock_set_unlock_disabled_summary);
358 pref.setEnabled(false);
359 }
360 }
361 }
362 }
363
Svetoslav52448442014-09-29 18:15:45 -0700364 private void updatePreferenceSummaryIfNeeded() {
Svetoslav40ca78f2014-10-17 14:37:02 -0700365 if (LockPatternUtils.isDeviceEncrypted()) {
366 return;
367 }
368
Svetoslav52448442014-09-29 18:15:45 -0700369 if (AccessibilityManager.getInstance(getActivity()).getEnabledAccessibilityServiceList(
370 AccessibilityServiceInfo.FEEDBACK_ALL_MASK).isEmpty()) {
371 return;
372 }
373
374 CharSequence summary = getString(R.string.secure_lock_encryption_warning);
375
376 PreferenceScreen screen = getPreferenceScreen();
377 final int preferenceCount = screen.getPreferenceCount();
378 for (int i = 0; i < preferenceCount; i++) {
379 Preference preference = screen.getPreference(i);
380 switch (preference.getKey()) {
381 case KEY_UNLOCK_SET_PATTERN:
382 case KEY_UNLOCK_SET_PIN:
383 case KEY_UNLOCK_SET_PASSWORD: {
384 preference.setSummary(summary);
385 } break;
386 }
387 }
388 }
389
Maurice Lam6b19fa92014-11-25 19:25:56 -0800390 protected Intent getLockPasswordIntent(Context context, int quality,
Adrian Roosf7887182015-01-07 20:51:57 +0100391 int minLength, final int maxLength,
Maurice Lam6b19fa92014-11-25 19:25:56 -0800392 boolean requirePasswordToDecrypt, boolean confirmCredentials) {
Adrian Roosf7887182015-01-07 20:51:57 +0100393 return ChooseLockPassword.createIntent(context, quality, minLength,
Maurice Lam6b19fa92014-11-25 19:25:56 -0800394 maxLength, requirePasswordToDecrypt, confirmCredentials);
395 }
396
Andres Morales6609b0c2015-04-12 15:38:25 -0700397 protected Intent getLockPasswordIntent(Context context, int quality,
398 int minLength, final int maxLength,
399 boolean requirePasswordToDecrypt, long challenge) {
400 return ChooseLockPassword.createIntent(context, quality, minLength,
401 maxLength, requirePasswordToDecrypt, challenge);
402 }
403
Maurice Lam38596432015-04-16 18:11:42 -0700404 protected Intent getLockPasswordIntent(Context context, int quality, int minLength,
Andres Moralesa0e12362015-04-02 09:00:41 -0700405 final int maxLength, boolean requirePasswordToDecrypt, String password) {
406 return ChooseLockPassword.createIntent(context, quality, minLength, maxLength,
407 requirePasswordToDecrypt, password);
408 }
409
Adrian Roosf7887182015-01-07 20:51:57 +0100410 protected Intent getLockPatternIntent(Context context, final boolean requirePassword,
411 final boolean confirmCredentials) {
412 return ChooseLockPattern.createIntent(context, requirePassword,
Maurice Lam6b19fa92014-11-25 19:25:56 -0800413 confirmCredentials);
414 }
415
Andres Morales6609b0c2015-04-12 15:38:25 -0700416 protected Intent getLockPatternIntent(Context context, final boolean requirePassword,
417 long challenge) {
418 return ChooseLockPattern.createIntent(context, requirePassword, challenge);
419 }
420
Maurice Lam38596432015-04-16 18:11:42 -0700421 protected Intent getLockPatternIntent(Context context, final boolean requirePassword,
Andres Moralesa0e12362015-04-02 09:00:41 -0700422 final String pattern) {
423 return ChooseLockPattern.createIntent(context, requirePassword, pattern);
424 }
425
Maurice Lamecd2b7b2014-12-01 10:41:49 -0800426 protected Intent getEncryptionInterstitialIntent(Context context, int quality,
427 boolean required) {
428 return EncryptionInterstitial.createStartIntent(context, quality, required);
429 }
430
Jim Miller5541a862011-09-02 17:33:53 -0700431 /**
Jim Miller17e9e192010-12-07 20:41:41 -0800432 * Invokes an activity to change the user's pattern, password or PIN based on given quality
433 * and minimum quality specified by DevicePolicyManager. If quality is
434 * {@link DevicePolicyManager#PASSWORD_QUALITY_UNSPECIFIED}, password is cleared.
435 *
Andy Stadler6370c872011-01-21 16:25:22 -0800436 * @param quality the desired quality. Ignored if DevicePolicyManager requires more security
Jim Miller17e9e192010-12-07 20:41:41 -0800437 * @param disabled whether or not to show LockScreen at all. Only meaningful when quality is
438 * {@link DevicePolicyManager#PASSWORD_QUALITY_UNSPECIFIED}
439 */
440 void updateUnlockMethodAndFinish(int quality, boolean disabled) {
Andy Stadler6370c872011-01-21 16:25:22 -0800441 // Sanity check. We should never get here without confirming user's existing password.
Jim Miller17e9e192010-12-07 20:41:41 -0800442 if (!mPasswordConfirmed) {
Andy Stadler6370c872011-01-21 16:25:22 -0800443 throw new IllegalStateException("Tried to update password without confirming it");
Jim Miller17e9e192010-12-07 20:41:41 -0800444 }
445
Adrian Roosf7887182015-01-07 20:51:57 +0100446 quality = upgradeQuality(quality);
Steven Rossc620ba42011-09-28 15:43:41 -0400447
Maurice Lam6b19fa92014-11-25 19:25:56 -0800448 final Context context = getActivity();
Jim Miller17e9e192010-12-07 20:41:41 -0800449 if (quality >= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) {
450 int minLength = mDPM.getPasswordMinimumLength(null);
451 if (minLength < MIN_PASSWORD_LENGTH) {
452 minLength = MIN_PASSWORD_LENGTH;
453 }
454 final int maxLength = mDPM.getPasswordMaximumLength(quality);
Andres Morales6609b0c2015-04-12 15:38:25 -0700455 Intent intent;
456 if (mHasChallenge) {
457 intent = getLockPasswordIntent(context, quality, minLength,
458 maxLength, mRequirePassword, mChallenge);
459 } else {
460 intent = getLockPasswordIntent(context, quality, minLength,
Andres Moralesa0e12362015-04-02 09:00:41 -0700461 maxLength, mRequirePassword, mUserPassword);
Andres Morales6609b0c2015-04-12 15:38:25 -0700462 }
Maurice Lam9066a5c2015-01-22 18:35:11 -0800463 startActivityForResult(intent, CHOOSE_LOCK_REQUEST);
Adrian Roosf7887182015-01-07 20:51:57 +0100464 } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
Andres Morales6609b0c2015-04-12 15:38:25 -0700465 Intent intent;
466 if (mHasChallenge) {
467 intent = getLockPatternIntent(context, mRequirePassword,
468 mChallenge);
469 } else {
470 intent = getLockPatternIntent(context, mRequirePassword,
Andres Moralesa0e12362015-04-02 09:00:41 -0700471 mUserPassword);
Andres Morales6609b0c2015-04-12 15:38:25 -0700472 }
Maurice Lam9066a5c2015-01-22 18:35:11 -0800473 startActivityForResult(intent, CHOOSE_LOCK_REQUEST);
Jim Miller17e9e192010-12-07 20:41:41 -0800474 } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
Adrian Roos54375882015-04-16 17:11:22 -0700475 mChooseLockSettingsHelper.utils().clearLock(UserHandle.myUserId());
476 mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled,
477 UserHandle.myUserId());
Jim Miller92186872015-03-04 18:07:32 -0800478 removeAllFingerprintTemplates();
Jim Miller17e9e192010-12-07 20:41:41 -0800479 getActivity().setResult(Activity.RESULT_OK);
Amith Yamasanic666c652012-10-24 10:27:05 -0700480 finish();
481 } else {
Jim Miller92186872015-03-04 18:07:32 -0800482 removeAllFingerprintTemplates();
Amith Yamasanic666c652012-10-24 10:27:05 -0700483 finish();
Jim Miller17e9e192010-12-07 20:41:41 -0800484 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700485 }
Amith Yamasanib0b37ae2012-04-23 15:35:36 -0700486
Jim Miller92186872015-03-04 18:07:32 -0800487 private void removeAllFingerprintTemplates() {
Jim Millerd52b5772015-03-12 10:33:53 -0700488 if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) {
Jim Millerd16c9b72015-03-24 16:02:59 -0700489 mFingerprintManager.remove(new Fingerprint(null, 0, 0, 0), mRemovalCallback);
Jim Miller92186872015-03-04 18:07:32 -0800490 }
491 }
492
493 @Override
494 public void onDestroy() {
495 super.onDestroy();
Jim Miller92186872015-03-04 18:07:32 -0800496 }
497
Amith Yamasanib0b37ae2012-04-23 15:35:36 -0700498 @Override
499 protected int getHelpResource() {
500 return R.string.help_url_choose_lockscreen;
501 }
502
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700503 private int getResIdForFactoryResetProtectionWarningMessage() {
504 boolean hasFingerprints = mFingerprintManager.hasEnrolledFingerprints();
Adrian Roos54375882015-04-16 17:11:22 -0700505 switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(UserHandle.myUserId())) {
Lucky Zhang3bcea022014-11-25 18:22:14 -0800506 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700507 return hasFingerprints
508 ? R.string.unlock_disable_frp_warning_content_pattern_fingerprint
509 : R.string.unlock_disable_frp_warning_content_pattern;
Lucky Zhang3bcea022014-11-25 18:22:14 -0800510 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
511 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700512 return hasFingerprints
513 ? R.string.unlock_disable_frp_warning_content_pin_fingerprint
514 : R.string.unlock_disable_frp_warning_content_pin;
Lucky Zhang3bcea022014-11-25 18:22:14 -0800515 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
516 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
517 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700518 return hasFingerprints
519 ? R.string.unlock_disable_frp_warning_content_password_fingerprint
520 : R.string.unlock_disable_frp_warning_content_password;
Lucky Zhang3bcea022014-11-25 18:22:14 -0800521 default:
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700522 return hasFingerprints
523 ? R.string.unlock_disable_frp_warning_content_unknown_fingerprint
524 : R.string.unlock_disable_frp_warning_content_unknown;
Lucky Zhang3bcea022014-11-25 18:22:14 -0800525 }
526 }
527
528 private boolean isUnlockMethodSecure(String unlockMethod) {
529 return !(KEY_UNLOCK_SET_OFF.equals(unlockMethod) ||
530 KEY_UNLOCK_SET_NONE.equals(unlockMethod));
531 }
532
533 private boolean setUnlockMethod(String unlockMethod) {
534 EventLog.writeEvent(EventLogTags.LOCK_SCREEN_TYPE, unlockMethod);
535
536 if (KEY_UNLOCK_SET_OFF.equals(unlockMethod)) {
537 updateUnlockMethodAndFinish(
538 DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, true /* disabled */ );
539 } else if (KEY_UNLOCK_SET_NONE.equals(unlockMethod)) {
540 updateUnlockMethodAndFinish(
541 DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, false /* disabled */ );
Lucky Zhang3bcea022014-11-25 18:22:14 -0800542 } else if (KEY_UNLOCK_SET_PATTERN.equals(unlockMethod)) {
543 maybeEnableEncryption(
544 DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, false);
545 } else if (KEY_UNLOCK_SET_PIN.equals(unlockMethod)) {
546 maybeEnableEncryption(
547 DevicePolicyManager.PASSWORD_QUALITY_NUMERIC, false);
548 } else if (KEY_UNLOCK_SET_PASSWORD.equals(unlockMethod)) {
549 maybeEnableEncryption(
550 DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC, false);
551 } else {
552 Log.e(TAG, "Encountered unknown unlock method to set: " + unlockMethod);
553 return false;
554 }
555 return true;
556 }
557
558 private void showFactoryResetProtectionWarningDialog(String unlockMethodToSet) {
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700559 int message = getResIdForFactoryResetProtectionWarningMessage();
Lucky Zhang3bcea022014-11-25 18:22:14 -0800560 FactoryResetProtectionWarningDialog dialog =
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700561 FactoryResetProtectionWarningDialog.newInstance(message, unlockMethodToSet);
Lucky Zhang3bcea022014-11-25 18:22:14 -0800562 dialog.show(getChildFragmentManager(), TAG_FRP_WARNING_DIALOG);
563 }
564
565 public static class FactoryResetProtectionWarningDialog extends DialogFragment {
566
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700567 private static final String ARG_MESSAGE_RES = "messageRes";
Lucky Zhang3bcea022014-11-25 18:22:14 -0800568 private static final String ARG_UNLOCK_METHOD_TO_SET = "unlockMethodToSet";
569
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700570 public static FactoryResetProtectionWarningDialog newInstance(int messageRes,
Lucky Zhang3bcea022014-11-25 18:22:14 -0800571 String unlockMethodToSet) {
572 FactoryResetProtectionWarningDialog frag =
573 new FactoryResetProtectionWarningDialog();
574 Bundle args = new Bundle();
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700575 args.putInt(ARG_MESSAGE_RES, messageRes);
Lucky Zhang3bcea022014-11-25 18:22:14 -0800576 args.putString(ARG_UNLOCK_METHOD_TO_SET, unlockMethodToSet);
577 frag.setArguments(args);
578 return frag;
579 }
580
581 @Override
582 public void show(FragmentManager manager, String tag) {
583 if (manager.findFragmentByTag(tag) == null) {
584 // Prevent opening multiple dialogs if tapped on button quickly
585 super.show(manager, tag);
586 }
587 }
588
589 @Override
590 public Dialog onCreateDialog(Bundle savedInstanceState) {
591 final Bundle args = getArguments();
592
593 return new AlertDialog.Builder(getActivity())
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700594 .setTitle(R.string.unlock_disable_frp_warning_title)
595 .setMessage(args.getInt(ARG_MESSAGE_RES))
596 .setPositiveButton(R.string.unlock_disable_frp_warning_ok,
Lucky Zhang3bcea022014-11-25 18:22:14 -0800597 new DialogInterface.OnClickListener() {
598 @Override
599 public void onClick(DialogInterface dialog, int whichButton) {
600 ((ChooseLockGenericFragment) getParentFragment())
601 .setUnlockMethod(
602 args.getString(ARG_UNLOCK_METHOD_TO_SET));
603 }
604 }
605 )
606 .setNegativeButton(R.string.cancel,
607 new DialogInterface.OnClickListener() {
608 @Override
609 public void onClick(DialogInterface dialog, int whichButton) {
610 dismiss();
611 }
612 }
613 )
614 .create();
615 }
616 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700617 }
Dianne Hackbornabc3dc62010-01-20 13:40:19 -0800618}