KeyguardSecurityModel.java revision 109f1fd80c90409c0d7f21d49989641dfdf2ad1b
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 updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
68        final IccCardConstants.State simState = updateMonitor.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                && mLockPatternUtils.isPukUnlockScreenEnable()) {
74            mode = SecurityMode.SimPuk;
75        } else {
76            final int security = mLockPatternUtils.getKeyguardStoredPasswordQuality();
77            switch (security) {
78                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
79                case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
80                case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
81                case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
82                    mode = mLockPatternUtils.isLockPasswordEnabled() ?
83                            SecurityMode.Password : SecurityMode.None;
84                    break;
85
86                case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
87                case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
88                    if (mLockPatternUtils.isLockPatternEnabled()) {
89                        mode = mLockPatternUtils.isPermanentlyLocked() ?
90                            SecurityMode.Account : SecurityMode.Pattern;
91                    }
92                    break;
93
94                default:
95                    throw new IllegalStateException("Unknown unlock mode:" + mode);
96            }
97        }
98        return mode;
99    }
100
101    /**
102     * Some unlock methods can have an alternate, such as biometric unlocks (e.g. face unlock).
103     * This function decides if an alternate unlock is available and returns it. Otherwise,
104     * returns @param mode.
105     *
106     * @param mode the mode we want the alternate for
107     * @return alternate or the given mode
108     */
109    SecurityMode getAlternateFor(SecurityMode mode) {
110        if (isBiometricUnlockEnabled()
111                && (mode == SecurityMode.Password || mode == SecurityMode.Pattern)) {
112            return SecurityMode.Biometric;
113        }
114        return mode; // no alternate, return what was given
115    }
116
117    /**
118     * Some unlock methods can have a backup which gives the user another way to get into
119     * the device. This is currently only supported for Biometric and Pattern unlock.
120     *
121     * @param mode the mode we want the backup for
122     * @return backup method or given mode
123     */
124    SecurityMode getBackupFor(SecurityMode mode) {
125        switch(mode) {
126            case Biometric:
127                return getSecurityMode();
128            case Pattern:
129                return SecurityMode.Account;
130        }
131        return mode; // no backup, return what was given
132    }
133}
134