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