blob: 1015a45b8d6ea16b6196214656856bc0b153f98d [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;
Maurice Lam87fadbe2015-08-03 15:33:25 -070041import android.view.LayoutInflater;
42import android.view.View;
Svetoslav52448442014-09-29 18:15:45 -070043import android.view.accessibility.AccessibilityManager;
Maurice Lam87fadbe2015-08-03 15:33:25 -070044import android.widget.ListView;
Jim Millerd16c9b72015-03-24 16:02:59 -070045import android.widget.Toast;
46
Chris Wren8a963ba2015-03-20 10:29:14 -040047import com.android.internal.logging.MetricsLogger;
Gilles Debunne64650542011-08-23 11:01:35 -070048import com.android.internal.widget.LockPatternUtils;
49
Fabrice Di Meglio263bcc82014-01-17 19:17:58 -080050public class ChooseLockGeneric extends SettingsActivity {
Jim Miller0698a212014-10-16 19:49:07 -070051 public static final String CONFIRM_CREDENTIALS = "confirm_credentials";
Dianne Hackbornabc3dc62010-01-20 13:40:19 -080052
53 @Override
Jim Miller17e9e192010-12-07 20:41:41 -080054 public Intent getIntent() {
55 Intent modIntent = new Intent(super.getIntent());
Maurice Lam52c75ba2014-11-25 14:06:38 -080056 modIntent.putExtra(EXTRA_SHOW_FRAGMENT, getFragmentClass().getName());
Jim Miller17e9e192010-12-07 20:41:41 -080057 return modIntent;
58 }
Jim Millerbbb4afa2010-04-08 19:40:19 -070059
Amith Yamasania677ee22013-07-26 13:38:41 -070060 @Override
61 protected boolean isValidFragment(String fragmentName) {
62 if (ChooseLockGenericFragment.class.getName().equals(fragmentName)) return true;
63 return false;
64 }
65
Maurice Lam52c75ba2014-11-25 14:06:38 -080066 /* package */ Class<? extends Fragment> getFragmentClass() {
67 return ChooseLockGenericFragment.class;
68 }
69
Amith Yamasani66026772013-09-25 14:05:33 -070070 public static class InternalActivity extends ChooseLockGeneric {
71 }
72
Jim Miller17e9e192010-12-07 20:41:41 -080073 public static class ChooseLockGenericFragment extends SettingsPreferenceFragment {
Jim Miller3fb2fb82015-03-11 20:17:39 -070074 private static final String TAG = "ChooseLockGenericFragment";
Jim Miller17e9e192010-12-07 20:41:41 -080075 private static final int MIN_PASSWORD_LENGTH = 4;
76 private static final String KEY_UNLOCK_SET_OFF = "unlock_set_off";
77 private static final String KEY_UNLOCK_SET_NONE = "unlock_set_none";
78 private static final String KEY_UNLOCK_SET_PIN = "unlock_set_pin";
79 private static final String KEY_UNLOCK_SET_PASSWORD = "unlock_set_password";
80 private static final String KEY_UNLOCK_SET_PATTERN = "unlock_set_pattern";
Jim Miller17e9e192010-12-07 20:41:41 -080081 private static final String PASSWORD_CONFIRMED = "password_confirmed";
Jim Miller47f1cd42012-04-27 18:11:03 -070082 private static final String WAITING_FOR_CONFIRMATION = "waiting_for_confirmation";
Brian Carlstromd4023b72011-05-25 13:24:20 -070083 public static final String MINIMUM_QUALITY_KEY = "minimum_quality";
Jim Miller3fb2fb82015-03-11 20:17:39 -070084 public static final String HIDE_DISABLED_PREFS = "hide_disabled_prefs";
Jim Miller46c7f6d2014-10-13 18:15:17 -070085 public static final String ENCRYPT_REQUESTED_QUALITY = "encrypt_requested_quality";
86 public static final String ENCRYPT_REQUESTED_DISABLED = "encrypt_requested_disabled";
Lucky Zhang3bcea022014-11-25 18:22:14 -080087 public static final String TAG_FRP_WARNING_DIALOG = "frp_warning_dialog";
Jim Millerbbb4afa2010-04-08 19:40:19 -070088
Jim Miller3fb2fb82015-03-11 20:17:39 -070089 private static final int CONFIRM_EXISTING_REQUEST = 100;
90 private static final int ENABLE_ENCRYPTION_REQUEST = 101;
91 private static final int CHOOSE_LOCK_REQUEST = 102;
Danielle Millett80412e72011-10-17 19:21:19 -040092
Jim Miller17e9e192010-12-07 20:41:41 -080093 private ChooseLockSettingsHelper mChooseLockSettingsHelper;
94 private DevicePolicyManager mDPM;
Brian Carlstromd4023b72011-05-25 13:24:20 -070095 private KeyStore mKeyStore;
Andres Morales6609b0c2015-04-12 15:38:25 -070096 private boolean mHasChallenge = false;
97 private long mChallenge;
Jim Miller17e9e192010-12-07 20:41:41 -080098 private boolean mPasswordConfirmed = false;
Jim Miller47f1cd42012-04-27 18:11:03 -070099 private boolean mWaitingForConfirmation = false;
Jim Miller46c7f6d2014-10-13 18:15:17 -0700100 private int mEncryptionRequestQuality;
101 private boolean mEncryptionRequestDisabled;
Jim Miller0698a212014-10-16 19:49:07 -0700102 private boolean mRequirePassword;
Maurice Lamc0e78792015-07-20 14:49:29 -0700103 private boolean mForFingerprint = false;
Andres Moralesa0e12362015-04-02 09:00:41 -0700104 private String mUserPassword;
Jim Miller0698a212014-10-16 19:49:07 -0700105 private LockPatternUtils mLockPatternUtils;
Jim Miller92186872015-03-04 18:07:32 -0800106 private FingerprintManager mFingerprintManager;
Jim Millerd16c9b72015-03-24 16:02:59 -0700107 private RemovalCallback mRemovalCallback = new RemovalCallback() {
108
109 @Override
110 public void onRemovalSucceeded(Fingerprint fingerprint) {
111 Log.v(TAG, "Fingerprint removed: " + fingerprint.getFingerId());
112 }
113
114 @Override
115 public void onRemovalError(Fingerprint fp, int errMsgId, CharSequence errString) {
116 Toast.makeText(getActivity(), errString, Toast.LENGTH_SHORT);
117 }
118 };
Jim Millerbbb4afa2010-04-08 19:40:19 -0700119
Jim Miller17e9e192010-12-07 20:41:41 -0800120 @Override
Chris Wren8a963ba2015-03-20 10:29:14 -0400121 protected int getMetricsCategory() {
122 return MetricsLogger.CHOOSE_LOCK_GENERIC;
123 }
124
125 @Override
Jim Miller17e9e192010-12-07 20:41:41 -0800126 public void onCreate(Bundle savedInstanceState) {
127 super.onCreate(savedInstanceState);
128
Jim Miller92186872015-03-04 18:07:32 -0800129 mFingerprintManager =
130 (FingerprintManager) getActivity().getSystemService(Context.FINGERPRINT_SERVICE);
Jim Miller17e9e192010-12-07 20:41:41 -0800131 mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
Brian Carlstromd4023b72011-05-25 13:24:20 -0700132 mKeyStore = KeyStore.getInstance();
Jim Miller17e9e192010-12-07 20:41:41 -0800133 mChooseLockSettingsHelper = new ChooseLockSettingsHelper(this.getActivity());
Jim Miller0698a212014-10-16 19:49:07 -0700134 mLockPatternUtils = new LockPatternUtils(getActivity());
Jim Miller17e9e192010-12-07 20:41:41 -0800135
Danielle Millettc474a882011-09-14 11:42:06 -0400136 // Defaults to needing to confirm credentials
137 final boolean confirmCredentials = getActivity().getIntent()
138 .getBooleanExtra(CONFIRM_CREDENTIALS, true);
Amith Yamasani66026772013-09-25 14:05:33 -0700139 if (getActivity() instanceof ChooseLockGeneric.InternalActivity) {
140 mPasswordConfirmed = !confirmCredentials;
141 }
Danielle Millettc474a882011-09-14 11:42:06 -0400142
Andres Morales6609b0c2015-04-12 15:38:25 -0700143 mHasChallenge = getActivity().getIntent().getBooleanExtra(
144 ChooseLockSettingsHelper.EXTRA_KEY_HAS_CHALLENGE, false);
145 mChallenge = getActivity().getIntent().getLongExtra(
146 ChooseLockSettingsHelper.EXTRA_KEY_CHALLENGE, 0);
Maurice Lamc0e78792015-07-20 14:49:29 -0700147 mForFingerprint = getActivity().getIntent().getBooleanExtra(
148 ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT, false);
Andres Morales6609b0c2015-04-12 15:38:25 -0700149
Jim Miller17e9e192010-12-07 20:41:41 -0800150 if (savedInstanceState != null) {
151 mPasswordConfirmed = savedInstanceState.getBoolean(PASSWORD_CONFIRMED);
Jim Miller47f1cd42012-04-27 18:11:03 -0700152 mWaitingForConfirmation = savedInstanceState.getBoolean(WAITING_FOR_CONFIRMATION);
Jim Miller46c7f6d2014-10-13 18:15:17 -0700153 mEncryptionRequestQuality = savedInstanceState.getInt(ENCRYPT_REQUESTED_QUALITY);
154 mEncryptionRequestDisabled = savedInstanceState.getBoolean(
155 ENCRYPT_REQUESTED_DISABLED);
Jim Miller17e9e192010-12-07 20:41:41 -0800156 }
157
Jim Miller47f1cd42012-04-27 18:11:03 -0700158 if (mPasswordConfirmed) {
159 updatePreferencesOrFinish();
160 } else if (!mWaitingForConfirmation) {
Andy Stadler6370c872011-01-21 16:25:22 -0800161 ChooseLockSettingsHelper helper =
162 new ChooseLockSettingsHelper(this.getActivity(), this);
Jorim Jaggi8a09b612015-04-06 17:47:18 -0700163 if (!helper.launchConfirmationActivity(CONFIRM_EXISTING_REQUEST,
Andres Moralesa0e12362015-04-02 09:00:41 -0700164 getString(R.string.unlock_set_unlock_launch_picker_title), true)) {
Jim Miller17e9e192010-12-07 20:41:41 -0800165 mPasswordConfirmed = true; // no password set, so no need to confirm
166 updatePreferencesOrFinish();
Jim Miller47f1cd42012-04-27 18:11:03 -0700167 } else {
168 mWaitingForConfirmation = true;
Jim Miller17e9e192010-12-07 20:41:41 -0800169 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700170 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700171 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700172
Amith Yamasanic666c652012-10-24 10:27:05 -0700173 @Override
Maurice Lam87fadbe2015-08-03 15:33:25 -0700174 public void onViewCreated(View view, Bundle savedInstanceState) {
175 super.onViewCreated(view, savedInstanceState);
176 if (mForFingerprint) {
177 final LayoutInflater inflater = LayoutInflater.from(getContext());
178 final ListView listView = getListView();
179 final View fingerprintHeader = inflater.inflate(
180 R.layout.choose_lock_generic_fingerprint_header, listView, false);
181 listView.addHeaderView(fingerprintHeader, null, false);
182 }
183 }
184
185 @Override
Jim Miller17e9e192010-12-07 20:41:41 -0800186 public boolean onPreferenceTreeClick(PreferenceScreen preferenceScreen,
187 Preference preference) {
188 final String key = preference.getKey();
rich cannings27d6f8d2013-05-29 14:54:58 -0700189
Adrian Roos54375882015-04-16 17:11:22 -0700190 if (!isUnlockMethodSecure(key) && mLockPatternUtils.isSecure(UserHandle.myUserId())) {
Lucky Zhang3bcea022014-11-25 18:22:14 -0800191 // Show the disabling FRP warning only when the user is switching from a secure
192 // unlock method to an insecure one
193 showFactoryResetProtectionWarningDialog(key);
194 return true;
Jim Miller17e9e192010-12-07 20:41:41 -0800195 } else {
Lucky Zhang3bcea022014-11-25 18:22:14 -0800196 return setUnlockMethod(key);
Jim Miller17e9e192010-12-07 20:41:41 -0800197 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700198 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700199
Jim Miller46c7f6d2014-10-13 18:15:17 -0700200 /**
201 * If the device has encryption already enabled, then ask the user if they
202 * also want to encrypt the phone with this password.
203 *
204 * @param quality
205 * @param disabled
206 */
Andres Moralesa0e12362015-04-02 09:00:41 -0700207 // TODO: why does this take disabled, its always called with a quality higher than
208 // what makes sense with disabled == true
Jim Miller46c7f6d2014-10-13 18:15:17 -0700209 private void maybeEnableEncryption(int quality, boolean disabled) {
Andrei Kapishnikov146fc112015-04-09 11:08:16 -0400210 DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(DEVICE_POLICY_SERVICE);
211 if (Process.myUserHandle().isOwner() && LockPatternUtils.isDeviceEncryptionEnabled()
212 && !dpm.getDoNotAskCredentialsOnBoot()) {
Jim Miller46c7f6d2014-10-13 18:15:17 -0700213 mEncryptionRequestQuality = quality;
214 mEncryptionRequestDisabled = disabled;
Maurice Lamecd2b7b2014-12-01 10:41:49 -0800215 final Context context = getActivity();
Jim Miller0698a212014-10-16 19:49:07 -0700216 // If accessibility is enabled and the user hasn't seen this dialog before, set the
217 // default state to agree with that which is compatible with accessibility
218 // (password not required).
Maurice Lamecd2b7b2014-12-01 10:41:49 -0800219 final boolean accEn = AccessibilityManager.getInstance(context).isEnabled();
Jim Miller0698a212014-10-16 19:49:07 -0700220 final boolean required = mLockPatternUtils.isCredentialRequiredToDecrypt(!accEn);
Maurice Lamecd2b7b2014-12-01 10:41:49 -0800221 Intent intent = getEncryptionInterstitialIntent(context, quality, required);
Maurice Lamc0e78792015-07-20 14:49:29 -0700222 intent.putExtra(ChooseLockSettingsHelper.EXTRA_KEY_FOR_FINGERPRINT,
223 mForFingerprint);
Jim Miller46c7f6d2014-10-13 18:15:17 -0700224 startActivityForResult(intent, ENABLE_ENCRYPTION_REQUEST);
225 } else {
Jim Miller0698a212014-10-16 19:49:07 -0700226 mRequirePassword = false; // device encryption not enabled or not device owner.
Jim Miller46c7f6d2014-10-13 18:15:17 -0700227 updateUnlockMethodAndFinish(quality, disabled);
228 }
229 }
230
Jim Miller17e9e192010-12-07 20:41:41 -0800231 @Override
232 public void onActivityResult(int requestCode, int resultCode, Intent data) {
233 super.onActivityResult(requestCode, resultCode, data);
Jim Miller47f1cd42012-04-27 18:11:03 -0700234 mWaitingForConfirmation = false;
Jim Miller17e9e192010-12-07 20:41:41 -0800235 if (requestCode == CONFIRM_EXISTING_REQUEST && resultCode == Activity.RESULT_OK) {
236 mPasswordConfirmed = true;
Andres Moralesa0e12362015-04-02 09:00:41 -0700237 mUserPassword = data.getStringExtra(ChooseLockSettingsHelper.EXTRA_KEY_PASSWORD);
Jim Miller17e9e192010-12-07 20:41:41 -0800238 updatePreferencesOrFinish();
Jim Miller46c7f6d2014-10-13 18:15:17 -0700239 } else if (requestCode == ENABLE_ENCRYPTION_REQUEST
240 && resultCode == Activity.RESULT_OK) {
Jim Miller0698a212014-10-16 19:49:07 -0700241 mRequirePassword = data.getBooleanExtra(
242 EncryptionInterstitial.EXTRA_REQUIRE_PASSWORD, true);
Jim Miller46c7f6d2014-10-13 18:15:17 -0700243 updateUnlockMethodAndFinish(mEncryptionRequestQuality, mEncryptionRequestDisabled);
Maurice Lam9066a5c2015-01-22 18:35:11 -0800244 } else if (requestCode == CHOOSE_LOCK_REQUEST) {
245 getActivity().setResult(resultCode, data);
246 finish();
Jim Miller17e9e192010-12-07 20:41:41 -0800247 } else {
248 getActivity().setResult(Activity.RESULT_CANCELED);
249 finish();
250 }
251 }
252
253 @Override
254 public void onSaveInstanceState(Bundle outState) {
255 super.onSaveInstanceState(outState);
256 // Saved so we don't force user to re-enter their password if configuration changes
257 outState.putBoolean(PASSWORD_CONFIRMED, mPasswordConfirmed);
Jim Miller47f1cd42012-04-27 18:11:03 -0700258 outState.putBoolean(WAITING_FOR_CONFIRMATION, mWaitingForConfirmation);
Jim Miller46c7f6d2014-10-13 18:15:17 -0700259 outState.putInt(ENCRYPT_REQUESTED_QUALITY, mEncryptionRequestQuality);
260 outState.putBoolean(ENCRYPT_REQUESTED_DISABLED, mEncryptionRequestDisabled);
Jim Miller17e9e192010-12-07 20:41:41 -0800261 }
262
263 private void updatePreferencesOrFinish() {
Jim Miller5541a862011-09-02 17:33:53 -0700264 Intent intent = getActivity().getIntent();
265 int quality = intent.getIntExtra(LockPatternUtils.PASSWORD_TYPE_KEY, -1);
Jim Miller17e9e192010-12-07 20:41:41 -0800266 if (quality == -1) {
Andy Stadler6370c872011-01-21 16:25:22 -0800267 // If caller didn't specify password quality, show UI and allow the user to choose.
Jim Miller5541a862011-09-02 17:33:53 -0700268 quality = intent.getIntExtra(MINIMUM_QUALITY_KEY, -1);
Adrian Roosf7887182015-01-07 20:51:57 +0100269 quality = upgradeQuality(quality);
Jim Miller3fb2fb82015-03-11 20:17:39 -0700270 final boolean hideDisabledPrefs = intent.getBooleanExtra(
271 HIDE_DISABLED_PREFS, false);
Jim Miller17e9e192010-12-07 20:41:41 -0800272 final PreferenceScreen prefScreen = getPreferenceScreen();
273 if (prefScreen != null) {
274 prefScreen.removeAll();
275 }
276 addPreferencesFromResource(R.xml.security_settings_picker);
Jim Miller3fb2fb82015-03-11 20:17:39 -0700277 disableUnusablePreferences(quality, hideDisabledPrefs);
Jason Monk9a64a422015-03-30 11:00:36 -0400278 updateCurrentPreference();
Svetoslav52448442014-09-29 18:15:45 -0700279 updatePreferenceSummaryIfNeeded();
Jim Miller17e9e192010-12-07 20:41:41 -0800280 } else {
281 updateUnlockMethodAndFinish(quality, false);
282 }
283 }
284
Jason Monk9a64a422015-03-30 11:00:36 -0400285 private void updateCurrentPreference() {
286 String currentKey = getKeyForCurrent();
287 Preference preference = findPreference(currentKey);
288 if (preference != null) {
289 preference.setSummary(R.string.current_screen_lock);
290 }
291 }
292
293 private String getKeyForCurrent() {
Adrian Roos54375882015-04-16 17:11:22 -0700294 if (mLockPatternUtils.isLockScreenDisabled(UserHandle.myUserId())) {
Jason Monk9a64a422015-03-30 11:00:36 -0400295 return KEY_UNLOCK_SET_OFF;
296 }
Adrian Roos54375882015-04-16 17:11:22 -0700297 switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(UserHandle.myUserId())) {
Jason Monk9a64a422015-03-30 11:00:36 -0400298 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
299 return KEY_UNLOCK_SET_PATTERN;
300 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
301 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
302 return KEY_UNLOCK_SET_PIN;
303 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
304 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
305 return KEY_UNLOCK_SET_PASSWORD;
306 case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
307 return KEY_UNLOCK_SET_NONE;
308 }
309 return null;
310 }
311
Adrian Roosf7887182015-01-07 20:51:57 +0100312 /** increases the quality if necessary */
313 private int upgradeQuality(int quality) {
Brian Carlstromd4023b72011-05-25 13:24:20 -0700314 quality = upgradeQualityForDPM(quality);
Paul Lawrenceb05f39d2014-02-04 10:22:19 -0800315 return quality;
Brian Carlstromd4023b72011-05-25 13:24:20 -0700316 }
317
318 private int upgradeQualityForDPM(int quality) {
319 // Compare min allowed password quality
320 int minQuality = mDPM.getPasswordQuality(null);
321 if (quality < minQuality) {
322 quality = minQuality;
323 }
324 return quality;
325 }
326
Jim Miller17e9e192010-12-07 20:41:41 -0800327 /***
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800328 * Disables preferences that are less secure than required quality. The actual
329 * implementation is in disableUnusablePreferenceImpl.
330 *
331 * @param quality the requested quality.
Jim Miller3fb2fb82015-03-11 20:17:39 -0700332 * @param hideDisabledPrefs if false preferences show why they were disabled; otherwise
333 * they're not shown at all.
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800334 */
Jim Miller3fb2fb82015-03-11 20:17:39 -0700335 protected void disableUnusablePreferences(final int quality, boolean hideDisabledPrefs) {
336 disableUnusablePreferencesImpl(quality, hideDisabledPrefs);
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800337 }
338
339 /***
Jim Miller17e9e192010-12-07 20:41:41 -0800340 * Disables preferences that are less secure than required quality.
341 *
342 * @param quality the requested quality.
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800343 * @param hideDisabled whether to hide disable screen lock options.
Jim Miller17e9e192010-12-07 20:41:41 -0800344 */
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800345 protected void disableUnusablePreferencesImpl(final int quality,
Adrian Roosf7887182015-01-07 20:51:57 +0100346 boolean hideDisabled) {
Amith Yamasanicf26bb22011-09-26 10:27:43 -0700347 final PreferenceScreen entries = getPreferenceScreen();
Jim Miller783ea852012-11-01 19:39:21 -0700348
Amith Yamasanicf26bb22011-09-26 10:27:43 -0700349 for (int i = entries.getPreferenceCount() - 1; i >= 0; --i) {
350 Preference pref = entries.getPreference(i);
Jim Miller17e9e192010-12-07 20:41:41 -0800351 if (pref instanceof PreferenceScreen) {
Adrian Roos591dc852015-04-07 16:55:29 +0200352 final String key = pref.getKey();
Jim Miller17e9e192010-12-07 20:41:41 -0800353 boolean enabled = true;
Jim Miller5541a862011-09-02 17:33:53 -0700354 boolean visible = true;
Amith Yamasanicf26bb22011-09-26 10:27:43 -0700355 if (KEY_UNLOCK_SET_OFF.equals(key)) {
Jim Miller17e9e192010-12-07 20:41:41 -0800356 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
357 } else if (KEY_UNLOCK_SET_NONE.equals(key)) {
358 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED;
359 } else if (KEY_UNLOCK_SET_PATTERN.equals(key)) {
360 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING;
361 } else if (KEY_UNLOCK_SET_PIN.equals(key)) {
Nicolas Prevot8fd852e2014-01-25 01:02:04 +0000362 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX;
Jim Miller17e9e192010-12-07 20:41:41 -0800363 } else if (KEY_UNLOCK_SET_PASSWORD.equals(key)) {
364 enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_COMPLEX;
365 }
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800366 if (hideDisabled) {
Adrian Roos591dc852015-04-07 16:55:29 +0200367 visible = enabled;
Lucky Zhangdf8566a2014-12-05 15:00:20 -0800368 }
Adrian Roosf7887182015-01-07 20:51:57 +0100369 if (!visible) {
Amith Yamasanicf26bb22011-09-26 10:27:43 -0700370 entries.removePreference(pref);
Jim Miller5541a862011-09-02 17:33:53 -0700371 } else if (!enabled) {
Jim Miller17e9e192010-12-07 20:41:41 -0800372 pref.setSummary(R.string.unlock_set_unlock_disabled_summary);
373 pref.setEnabled(false);
374 }
375 }
376 }
377 }
378
Svetoslav52448442014-09-29 18:15:45 -0700379 private void updatePreferenceSummaryIfNeeded() {
Svetoslav40ca78f2014-10-17 14:37:02 -0700380 if (LockPatternUtils.isDeviceEncrypted()) {
381 return;
382 }
383
Svetoslav52448442014-09-29 18:15:45 -0700384 if (AccessibilityManager.getInstance(getActivity()).getEnabledAccessibilityServiceList(
385 AccessibilityServiceInfo.FEEDBACK_ALL_MASK).isEmpty()) {
386 return;
387 }
388
389 CharSequence summary = getString(R.string.secure_lock_encryption_warning);
390
391 PreferenceScreen screen = getPreferenceScreen();
392 final int preferenceCount = screen.getPreferenceCount();
393 for (int i = 0; i < preferenceCount; i++) {
394 Preference preference = screen.getPreference(i);
395 switch (preference.getKey()) {
396 case KEY_UNLOCK_SET_PATTERN:
397 case KEY_UNLOCK_SET_PIN:
398 case KEY_UNLOCK_SET_PASSWORD: {
399 preference.setSummary(summary);
400 } break;
401 }
402 }
403 }
404
Maurice Lam6b19fa92014-11-25 19:25:56 -0800405 protected Intent getLockPasswordIntent(Context context, int quality,
Adrian Roosf7887182015-01-07 20:51:57 +0100406 int minLength, final int maxLength,
Maurice Lam6b19fa92014-11-25 19:25:56 -0800407 boolean requirePasswordToDecrypt, boolean confirmCredentials) {
Adrian Roosf7887182015-01-07 20:51:57 +0100408 return ChooseLockPassword.createIntent(context, quality, minLength,
Maurice Lam6b19fa92014-11-25 19:25:56 -0800409 maxLength, requirePasswordToDecrypt, confirmCredentials);
410 }
411
Andres Morales6609b0c2015-04-12 15:38:25 -0700412 protected Intent getLockPasswordIntent(Context context, int quality,
413 int minLength, final int maxLength,
414 boolean requirePasswordToDecrypt, long challenge) {
415 return ChooseLockPassword.createIntent(context, quality, minLength,
416 maxLength, requirePasswordToDecrypt, challenge);
417 }
418
Maurice Lam38596432015-04-16 18:11:42 -0700419 protected Intent getLockPasswordIntent(Context context, int quality, int minLength,
Andres Moralesa0e12362015-04-02 09:00:41 -0700420 final int maxLength, boolean requirePasswordToDecrypt, String password) {
421 return ChooseLockPassword.createIntent(context, quality, minLength, maxLength,
422 requirePasswordToDecrypt, password);
423 }
424
Adrian Roosf7887182015-01-07 20:51:57 +0100425 protected Intent getLockPatternIntent(Context context, final boolean requirePassword,
426 final boolean confirmCredentials) {
427 return ChooseLockPattern.createIntent(context, requirePassword,
Maurice Lam6b19fa92014-11-25 19:25:56 -0800428 confirmCredentials);
429 }
430
Andres Morales6609b0c2015-04-12 15:38:25 -0700431 protected Intent getLockPatternIntent(Context context, final boolean requirePassword,
432 long challenge) {
433 return ChooseLockPattern.createIntent(context, requirePassword, challenge);
434 }
435
Maurice Lam38596432015-04-16 18:11:42 -0700436 protected Intent getLockPatternIntent(Context context, final boolean requirePassword,
Andres Moralesa0e12362015-04-02 09:00:41 -0700437 final String pattern) {
438 return ChooseLockPattern.createIntent(context, requirePassword, pattern);
439 }
440
Maurice Lamecd2b7b2014-12-01 10:41:49 -0800441 protected Intent getEncryptionInterstitialIntent(Context context, int quality,
442 boolean required) {
443 return EncryptionInterstitial.createStartIntent(context, quality, required);
444 }
445
Jim Miller5541a862011-09-02 17:33:53 -0700446 /**
Jim Miller17e9e192010-12-07 20:41:41 -0800447 * Invokes an activity to change the user's pattern, password or PIN based on given quality
448 * and minimum quality specified by DevicePolicyManager. If quality is
449 * {@link DevicePolicyManager#PASSWORD_QUALITY_UNSPECIFIED}, password is cleared.
450 *
Andy Stadler6370c872011-01-21 16:25:22 -0800451 * @param quality the desired quality. Ignored if DevicePolicyManager requires more security
Jim Miller17e9e192010-12-07 20:41:41 -0800452 * @param disabled whether or not to show LockScreen at all. Only meaningful when quality is
453 * {@link DevicePolicyManager#PASSWORD_QUALITY_UNSPECIFIED}
454 */
455 void updateUnlockMethodAndFinish(int quality, boolean disabled) {
Andy Stadler6370c872011-01-21 16:25:22 -0800456 // Sanity check. We should never get here without confirming user's existing password.
Jim Miller17e9e192010-12-07 20:41:41 -0800457 if (!mPasswordConfirmed) {
Andy Stadler6370c872011-01-21 16:25:22 -0800458 throw new IllegalStateException("Tried to update password without confirming it");
Jim Miller17e9e192010-12-07 20:41:41 -0800459 }
460
Adrian Roosf7887182015-01-07 20:51:57 +0100461 quality = upgradeQuality(quality);
Steven Rossc620ba42011-09-28 15:43:41 -0400462
Maurice Lam6b19fa92014-11-25 19:25:56 -0800463 final Context context = getActivity();
Jim Miller17e9e192010-12-07 20:41:41 -0800464 if (quality >= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) {
465 int minLength = mDPM.getPasswordMinimumLength(null);
466 if (minLength < MIN_PASSWORD_LENGTH) {
467 minLength = MIN_PASSWORD_LENGTH;
468 }
469 final int maxLength = mDPM.getPasswordMaximumLength(quality);
Andres Morales6609b0c2015-04-12 15:38:25 -0700470 Intent intent;
471 if (mHasChallenge) {
472 intent = getLockPasswordIntent(context, quality, minLength,
473 maxLength, mRequirePassword, mChallenge);
474 } else {
475 intent = getLockPasswordIntent(context, quality, minLength,
Andres Moralesa0e12362015-04-02 09:00:41 -0700476 maxLength, mRequirePassword, mUserPassword);
Andres Morales6609b0c2015-04-12 15:38:25 -0700477 }
Maurice Lam9066a5c2015-01-22 18:35:11 -0800478 startActivityForResult(intent, CHOOSE_LOCK_REQUEST);
Adrian Roosf7887182015-01-07 20:51:57 +0100479 } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_SOMETHING) {
Andres Morales6609b0c2015-04-12 15:38:25 -0700480 Intent intent;
481 if (mHasChallenge) {
482 intent = getLockPatternIntent(context, mRequirePassword,
483 mChallenge);
484 } else {
485 intent = getLockPatternIntent(context, mRequirePassword,
Andres Moralesa0e12362015-04-02 09:00:41 -0700486 mUserPassword);
Andres Morales6609b0c2015-04-12 15:38:25 -0700487 }
Maurice Lam9066a5c2015-01-22 18:35:11 -0800488 startActivityForResult(intent, CHOOSE_LOCK_REQUEST);
Jim Miller17e9e192010-12-07 20:41:41 -0800489 } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED) {
Adrian Roos54375882015-04-16 17:11:22 -0700490 mChooseLockSettingsHelper.utils().clearLock(UserHandle.myUserId());
491 mChooseLockSettingsHelper.utils().setLockScreenDisabled(disabled,
492 UserHandle.myUserId());
Jim Miller92186872015-03-04 18:07:32 -0800493 removeAllFingerprintTemplates();
Jim Miller17e9e192010-12-07 20:41:41 -0800494 getActivity().setResult(Activity.RESULT_OK);
Amith Yamasanic666c652012-10-24 10:27:05 -0700495 finish();
496 } else {
Jim Miller92186872015-03-04 18:07:32 -0800497 removeAllFingerprintTemplates();
Amith Yamasanic666c652012-10-24 10:27:05 -0700498 finish();
Jim Miller17e9e192010-12-07 20:41:41 -0800499 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700500 }
Amith Yamasanib0b37ae2012-04-23 15:35:36 -0700501
Jim Miller92186872015-03-04 18:07:32 -0800502 private void removeAllFingerprintTemplates() {
Jim Millerd52b5772015-03-12 10:33:53 -0700503 if (mFingerprintManager != null && mFingerprintManager.isHardwareDetected()) {
Jim Millerd16c9b72015-03-24 16:02:59 -0700504 mFingerprintManager.remove(new Fingerprint(null, 0, 0, 0), mRemovalCallback);
Jim Miller92186872015-03-04 18:07:32 -0800505 }
506 }
507
508 @Override
509 public void onDestroy() {
510 super.onDestroy();
Jim Miller92186872015-03-04 18:07:32 -0800511 }
512
Amith Yamasanib0b37ae2012-04-23 15:35:36 -0700513 @Override
514 protected int getHelpResource() {
515 return R.string.help_url_choose_lockscreen;
516 }
517
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700518 private int getResIdForFactoryResetProtectionWarningMessage() {
519 boolean hasFingerprints = mFingerprintManager.hasEnrolledFingerprints();
Adrian Roos54375882015-04-16 17:11:22 -0700520 switch (mLockPatternUtils.getKeyguardStoredPasswordQuality(UserHandle.myUserId())) {
Lucky Zhang3bcea022014-11-25 18:22:14 -0800521 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700522 return hasFingerprints
523 ? R.string.unlock_disable_frp_warning_content_pattern_fingerprint
524 : R.string.unlock_disable_frp_warning_content_pattern;
Lucky Zhang3bcea022014-11-25 18:22:14 -0800525 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
526 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC_COMPLEX:
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700527 return hasFingerprints
528 ? R.string.unlock_disable_frp_warning_content_pin_fingerprint
529 : R.string.unlock_disable_frp_warning_content_pin;
Lucky Zhang3bcea022014-11-25 18:22:14 -0800530 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
531 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
532 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700533 return hasFingerprints
534 ? R.string.unlock_disable_frp_warning_content_password_fingerprint
535 : R.string.unlock_disable_frp_warning_content_password;
Lucky Zhang3bcea022014-11-25 18:22:14 -0800536 default:
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700537 return hasFingerprints
538 ? R.string.unlock_disable_frp_warning_content_unknown_fingerprint
539 : R.string.unlock_disable_frp_warning_content_unknown;
Lucky Zhang3bcea022014-11-25 18:22:14 -0800540 }
541 }
542
543 private boolean isUnlockMethodSecure(String unlockMethod) {
544 return !(KEY_UNLOCK_SET_OFF.equals(unlockMethod) ||
545 KEY_UNLOCK_SET_NONE.equals(unlockMethod));
546 }
547
548 private boolean setUnlockMethod(String unlockMethod) {
549 EventLog.writeEvent(EventLogTags.LOCK_SCREEN_TYPE, unlockMethod);
550
551 if (KEY_UNLOCK_SET_OFF.equals(unlockMethod)) {
552 updateUnlockMethodAndFinish(
553 DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, true /* disabled */ );
554 } else if (KEY_UNLOCK_SET_NONE.equals(unlockMethod)) {
555 updateUnlockMethodAndFinish(
556 DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED, false /* disabled */ );
Lucky Zhang3bcea022014-11-25 18:22:14 -0800557 } else if (KEY_UNLOCK_SET_PATTERN.equals(unlockMethod)) {
558 maybeEnableEncryption(
559 DevicePolicyManager.PASSWORD_QUALITY_SOMETHING, false);
560 } else if (KEY_UNLOCK_SET_PIN.equals(unlockMethod)) {
561 maybeEnableEncryption(
562 DevicePolicyManager.PASSWORD_QUALITY_NUMERIC, false);
563 } else if (KEY_UNLOCK_SET_PASSWORD.equals(unlockMethod)) {
564 maybeEnableEncryption(
565 DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC, false);
566 } else {
567 Log.e(TAG, "Encountered unknown unlock method to set: " + unlockMethod);
568 return false;
569 }
570 return true;
571 }
572
573 private void showFactoryResetProtectionWarningDialog(String unlockMethodToSet) {
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700574 int message = getResIdForFactoryResetProtectionWarningMessage();
Lucky Zhang3bcea022014-11-25 18:22:14 -0800575 FactoryResetProtectionWarningDialog dialog =
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700576 FactoryResetProtectionWarningDialog.newInstance(message, unlockMethodToSet);
Lucky Zhang3bcea022014-11-25 18:22:14 -0800577 dialog.show(getChildFragmentManager(), TAG_FRP_WARNING_DIALOG);
578 }
579
580 public static class FactoryResetProtectionWarningDialog extends DialogFragment {
581
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700582 private static final String ARG_MESSAGE_RES = "messageRes";
Lucky Zhang3bcea022014-11-25 18:22:14 -0800583 private static final String ARG_UNLOCK_METHOD_TO_SET = "unlockMethodToSet";
584
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700585 public static FactoryResetProtectionWarningDialog newInstance(int messageRes,
Lucky Zhang3bcea022014-11-25 18:22:14 -0800586 String unlockMethodToSet) {
587 FactoryResetProtectionWarningDialog frag =
588 new FactoryResetProtectionWarningDialog();
589 Bundle args = new Bundle();
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700590 args.putInt(ARG_MESSAGE_RES, messageRes);
Lucky Zhang3bcea022014-11-25 18:22:14 -0800591 args.putString(ARG_UNLOCK_METHOD_TO_SET, unlockMethodToSet);
592 frag.setArguments(args);
593 return frag;
594 }
595
596 @Override
597 public void show(FragmentManager manager, String tag) {
598 if (manager.findFragmentByTag(tag) == null) {
599 // Prevent opening multiple dialogs if tapped on button quickly
600 super.show(manager, tag);
601 }
602 }
603
604 @Override
605 public Dialog onCreateDialog(Bundle savedInstanceState) {
606 final Bundle args = getArguments();
607
608 return new AlertDialog.Builder(getActivity())
Adrian Roos38c9b9e2015-07-24 11:30:14 -0700609 .setTitle(R.string.unlock_disable_frp_warning_title)
610 .setMessage(args.getInt(ARG_MESSAGE_RES))
611 .setPositiveButton(R.string.unlock_disable_frp_warning_ok,
Lucky Zhang3bcea022014-11-25 18:22:14 -0800612 new DialogInterface.OnClickListener() {
613 @Override
614 public void onClick(DialogInterface dialog, int whichButton) {
615 ((ChooseLockGenericFragment) getParentFragment())
616 .setUnlockMethod(
617 args.getString(ARG_UNLOCK_METHOD_TO_SET));
618 }
619 }
620 )
621 .setNegativeButton(R.string.cancel,
622 new DialogInterface.OnClickListener() {
623 @Override
624 public void onClick(DialogInterface dialog, int whichButton) {
625 dismiss();
626 }
627 }
628 )
629 .create();
630 }
631 }
Jim Millerbbb4afa2010-04-08 19:40:19 -0700632 }
Dianne Hackbornabc3dc62010-01-20 13:40:19 -0800633}