From 94c05482240f743daa8c8698a241d1d0dfe2404c Mon Sep 17 00:00:00 2001 From: Steven Ross Date: Fri, 11 Nov 2011 13:35:09 -0500 Subject: [PATCH] Allowing FaceUnlock with a PIN fixes 5467194 We need to allow FaceUnlock if the backup lock supports encryption (PIN). This requires changing the way the minimum encryption quality is enforced to allow FaceUnlock as long as the backup lock is a PIN, as FaceUnlock is considered a lower security than the minimum for encrypted drives. This change adds some complexity to upgradeQualityForEncryption because it's used in two places: once to grey out selections that aren't sufficient security level, and second to force the user to use a higher security level. This still increases the minimum security level, but makes an exception for FaceUnlock if it's allowed without encryption. This uses a MutableBoolean to provide a mutable boolean capability. We could instead write a custom one or use some other type of mutable boolean if it exists. In CryptKeeperSettings, using getKeyguardStoredPasswordQuality directly instead of getActivePasswordQuality is simpler, but this uses a more complex approach with a minor tweak as jaggies suggested it and it is clear about the biometric exception being made. Change-Id: Ia2645d6bd98857c79c6a9be45eda98087bfe517a --- .../android/settings/ChooseLockGeneric.java | 33 ++++++++++++++----- .../android/settings/CryptKeeperSettings.java | 9 ++++- 2 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/com/android/settings/ChooseLockGeneric.java b/src/com/android/settings/ChooseLockGeneric.java index df421a24713..88f7ae67b2f 100644 --- a/src/com/android/settings/ChooseLockGeneric.java +++ b/src/com/android/settings/ChooseLockGeneric.java @@ -33,6 +33,8 @@ import android.widget.ListView; import com.android.internal.widget.LockPatternUtils; +import libcore.util.MutableBoolean; + public class ChooseLockGeneric extends PreferenceActivity { @Override @@ -167,23 +169,37 @@ public class ChooseLockGeneric extends PreferenceActivity { if (quality == -1) { // If caller didn't specify password quality, show UI and allow the user to choose. quality = intent.getIntExtra(MINIMUM_QUALITY_KEY, -1); - quality = upgradeQuality(quality); + MutableBoolean allowBiometric = new MutableBoolean(false); + quality = upgradeQuality(quality, allowBiometric); final PreferenceScreen prefScreen = getPreferenceScreen(); if (prefScreen != null) { prefScreen.removeAll(); } addPreferencesFromResource(R.xml.security_settings_picker); - disableUnusablePreferences(quality); + disableUnusablePreferences(quality, allowBiometric); } else { updateUnlockMethodAndFinish(quality, false); } } - private int upgradeQuality(int quality) { + /** increases the quality if necessary, and returns whether biometric is allowed */ + private int upgradeQuality(int quality, MutableBoolean allowBiometric) { quality = upgradeQualityForDPM(quality); - quality = upgradeQualityForEncryption(quality); quality = upgradeQualityForKeyStore(quality); - return quality; + int encryptionQuality = upgradeQualityForEncryption(quality); + if (encryptionQuality > quality) { + //The first case checks whether biometric is allowed, prior to the user making + //their selection from the list + if (allowBiometric != null) { + allowBiometric.value = quality <= + DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK; + } else if (quality == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK) { + //When the user has selected biometric we shouldn't change that due to + //encryption + return quality; + } + } + return encryptionQuality; } private int upgradeQualityForDPM(int quality) { @@ -228,7 +244,7 @@ public class ChooseLockGeneric extends PreferenceActivity { * * @param quality the requested quality. */ - private void disableUnusablePreferences(final int quality) { + private void disableUnusablePreferences(final int quality, MutableBoolean allowBiometric) { final PreferenceScreen entries = getPreferenceScreen(); final boolean onlyShowFallback = getActivity().getIntent() .getBooleanExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK, false); @@ -245,7 +261,8 @@ public class ChooseLockGeneric extends PreferenceActivity { } else if (KEY_UNLOCK_SET_NONE.equals(key)) { enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED; } else if (KEY_UNLOCK_SET_BIOMETRIC_WEAK.equals(key)) { - enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK; + enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK || + allowBiometric.value; visible = weakBiometricAvailable; // If not available, then don't show it. } else if (KEY_UNLOCK_SET_PATTERN.equals(key)) { enabled = quality <= DevicePolicyManager.PASSWORD_QUALITY_SOMETHING; @@ -311,7 +328,7 @@ public class ChooseLockGeneric extends PreferenceActivity { final boolean isFallback = getActivity().getIntent() .getBooleanExtra(LockPatternUtils.LOCKSCREEN_BIOMETRIC_WEAK_FALLBACK, false); - quality = upgradeQuality(quality); + quality = upgradeQuality(quality, null); if (quality >= DevicePolicyManager.PASSWORD_QUALITY_NUMERIC) { int minLength = mDPM.getPasswordMinimumLength(null); diff --git a/src/com/android/settings/CryptKeeperSettings.java b/src/com/android/settings/CryptKeeperSettings.java index 41a4be5236b..ce3ad9d326e 100644 --- a/src/com/android/settings/CryptKeeperSettings.java +++ b/src/com/android/settings/CryptKeeperSettings.java @@ -159,7 +159,14 @@ public class CryptKeeperSettings extends Fragment { */ private boolean runKeyguardConfirmation(int request) { // 1. Confirm that we have a sufficient PIN/Password to continue - int quality = new LockPatternUtils(getActivity()).getActivePasswordQuality(); + LockPatternUtils lockPatternUtils = new LockPatternUtils(getActivity()); + int quality = lockPatternUtils.getActivePasswordQuality(); + if (quality == DevicePolicyManager.PASSWORD_QUALITY_BIOMETRIC_WEAK + && lockPatternUtils.isLockPasswordEnabled()) { + // Use the alternate as the quality. We expect this to be + // PASSWORD_QUALITY_SOMETHING(pattern) or PASSWORD_QUALITY_NUMERIC(PIN). + quality = lockPatternUtils.getKeyguardStoredPasswordQuality(); + } if (quality < MIN_PASSWORD_QUALITY) { return false; }