Home | History | Annotate | Download | only in keyguard
      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