1 /* 2 * Copyright (C) 2012 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 package com.android.keyguard; 17 18 import android.app.admin.DevicePolicyManager; 19 import android.content.Context; 20 import android.telephony.TelephonyManager; 21 22 import com.android.internal.telephony.IccCardConstants; 23 import com.android.internal.widget.LockPatternUtils; 24 25 public class KeyguardSecurityModel { 26 /** 27 * The different types of security available for {@link Mode#UnlockScreen}. 28 * @see com.android.internal.policy.impl.LockPatternKeyguardView#getUnlockMode() 29 */ 30 enum SecurityMode { 31 Invalid, // NULL state 32 None, // No security enabled 33 Pattern, // Unlock by drawing a pattern. 34 Password, // Unlock by entering an alphanumeric password 35 PIN, // Strictly numeric password 36 Biometric, // Unlock with a biometric key (e.g. finger print or face unlock) 37 Account, // Unlock by entering an account's login and password. 38 SimPin, // Unlock by entering a sim pin. 39 SimPuk // Unlock by entering a sim puk 40 } 41 42 private Context mContext; 43 private LockPatternUtils mLockPatternUtils; 44 45 KeyguardSecurityModel(Context context) { 46 mContext = context; 47 mLockPatternUtils = new LockPatternUtils(context); 48 } 49 50 void setLockPatternUtils(LockPatternUtils utils) { 51 mLockPatternUtils = utils; 52 } 53 54 /** 55 * Returns true if biometric unlock is installed and selected. If this returns false there is 56 * no need to even construct the biometric unlock. 57 */ 58 boolean isBiometricUnlockEnabled() { 59 return mLockPatternUtils.usingBiometricWeak() 60 && mLockPatternUtils.isBiometricWeakInstalled(); 61 } 62 63 /** 64 * Returns true if a condition is currently suppressing the biometric unlock. If this returns 65 * true there is no need to even construct the biometric unlock. 66 */ 67 private boolean isBiometricUnlockSuppressed() { 68 KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext); 69 final boolean backupIsTimedOut = monitor.getFailedUnlockAttempts() >= 70 LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT; 71 return monitor.getMaxBiometricUnlockAttemptsReached() || backupIsTimedOut 72 || !monitor.isAlternateUnlockEnabled() 73 || monitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE; 74 } 75 76 SecurityMode getSecurityMode() { 77 KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext); 78 final IccCardConstants.State simState = updateMonitor.getSimState(); 79 SecurityMode mode = SecurityMode.None; 80 if (simState == IccCardConstants.State.PIN_REQUIRED) { 81 mode = SecurityMode.SimPin; 82 } else if (simState == IccCardConstants.State.PUK_REQUIRED 83 && mLockPatternUtils.isPukUnlockScreenEnable()) { 84 mode = SecurityMode.SimPuk; 85 } else { 86 final int security = mLockPatternUtils.getKeyguardStoredPasswordQuality(); 87 switch (security) { 88 case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC: 89 mode = mLockPatternUtils.isLockPasswordEnabled() ? 90 SecurityMode.PIN : SecurityMode.None; 91 break; 92 case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC: 93 case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC: 94 case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX: 95 mode = mLockPatternUtils.isLockPasswordEnabled() ? 96 SecurityMode.Password : SecurityMode.None; 97 break; 98 99 case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING: 100 case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED: 101 if (mLockPatternUtils.isLockPatternEnabled()) { 102 mode = mLockPatternUtils.isPermanentlyLocked() ? 103 SecurityMode.Account : SecurityMode.Pattern; 104 } 105 break; 106 107 default: 108 throw new IllegalStateException("Unknown unlock mode:" + mode); 109 } 110 } 111 return mode; 112 } 113 114 /** 115 * Some unlock methods can have an alternate, such as biometric unlocks (e.g. face unlock). 116 * This function decides if an alternate unlock is available and returns it. Otherwise, 117 * returns @param mode. 118 * 119 * @param mode the mode we want the alternate for 120 * @return alternate or the given mode 121 */ 122 SecurityMode getAlternateFor(SecurityMode mode) { 123 if (isBiometricUnlockEnabled() && !isBiometricUnlockSuppressed() 124 && (mode == SecurityMode.Password 125 || mode == SecurityMode.PIN 126 || mode == SecurityMode.Pattern)) { 127 return SecurityMode.Biometric; 128 } 129 return mode; // no alternate, return what was given 130 } 131 132 /** 133 * Some unlock methods can have a backup which gives the user another way to get into 134 * the device. This is currently only supported for Biometric and Pattern unlock. 135 * 136 * @return backup method or current security mode 137 */ 138 SecurityMode getBackupSecurityMode(SecurityMode mode) { 139 switch(mode) { 140 case Biometric: 141 return getSecurityMode(); 142 case Pattern: 143 return SecurityMode.Account; 144 } 145 return mode; // no backup, return current security mode 146 } 147 } 148