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.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