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