1dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller/*
2dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Copyright (C) 2012 The Android Open Source Project
3dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller *
4dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Licensed under the Apache License, Version 2.0 (the "License");
5dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * you may not use this file except in compliance with the License.
6dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * You may obtain a copy of the License at
7dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller *
8dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller *      http://www.apache.org/licenses/LICENSE-2.0
9dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller *
10dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * Unless required by applicable law or agreed to in writing, software
11dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * distributed under the License is distributed on an "AS IS" BASIS,
12dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * See the License for the specific language governing permissions and
14dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller * limitations under the License.
15dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller */
165ecd81154fa039961f65bb4e36d18ac555b0d1d6Jim Millerpackage com.android.keyguard;
17dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
18dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.app.admin.DevicePolicyManager;
19dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport android.content.Context;
20d95c659a1d621dfbdd892759419ffc089e248672Danielle Millettimport android.telephony.TelephonyManager;
21dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
22dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport com.android.internal.telephony.IccCardConstants;
23dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerimport com.android.internal.widget.LockPatternUtils;
24dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
25dcb3d84b82cc2448d04e73359a716581bfb657dbJim Millerpublic class KeyguardSecurityModel {
26dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    /**
27dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller     * The different types of security available for {@link Mode#UnlockScreen}.
28dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller     * @see com.android.internal.policy.impl.LockPatternKeyguardView#getUnlockMode()
29dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller     */
30dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    enum SecurityMode {
3163f9b81795559443e0376985f8aaaa97a359ef94Jim Miller        Invalid, // NULL state
32dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        None, // No security enabled
33dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        Pattern, // Unlock by drawing a pattern.
3469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        Password, // Unlock by entering an alphanumeric password
3569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler        PIN, // Strictly numeric password
36dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        Biometric, // Unlock with a biometric key (e.g. finger print or face unlock)
37dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        Account, // Unlock by entering an account's login and password.
38dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        SimPin, // Unlock by entering a sim pin.
39dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        SimPuk // Unlock by entering a sim puk
40dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
41dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
42dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private Context mContext;
43dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    private LockPatternUtils mLockPatternUtils;
44dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
45dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    KeyguardSecurityModel(Context context) {
46dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mContext = context;
47dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternUtils = new LockPatternUtils(context);
48dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
49dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
50dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    void setLockPatternUtils(LockPatternUtils utils) {
51dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        mLockPatternUtils = utils;
52dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
53dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
54258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    /**
559ded0e1d48c016883858dd2dc574787524c6df84Brian Colonna     * Returns true if biometric unlock is installed and selected.  If this returns false there is
569ded0e1d48c016883858dd2dc574787524c6df84Brian Colonna     * no need to even construct the biometric unlock.
57258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     */
5863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    boolean isBiometricUnlockEnabled() {
59258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        return mLockPatternUtils.usingBiometricWeak()
609ded0e1d48c016883858dd2dc574787524c6df84Brian Colonna                && mLockPatternUtils.isBiometricWeakInstalled();
619ded0e1d48c016883858dd2dc574787524c6df84Brian Colonna    }
629ded0e1d48c016883858dd2dc574787524c6df84Brian Colonna
639ded0e1d48c016883858dd2dc574787524c6df84Brian Colonna    /**
649ded0e1d48c016883858dd2dc574787524c6df84Brian Colonna     * Returns true if a condition is currently suppressing the biometric unlock.  If this returns
659ded0e1d48c016883858dd2dc574787524c6df84Brian Colonna     * true there is no need to even construct the biometric unlock.
669ded0e1d48c016883858dd2dc574787524c6df84Brian Colonna     */
679ded0e1d48c016883858dd2dc574787524c6df84Brian Colonna    private boolean isBiometricUnlockSuppressed() {
689ded0e1d48c016883858dd2dc574787524c6df84Brian Colonna        KeyguardUpdateMonitor monitor = KeyguardUpdateMonitor.getInstance(mContext);
699ded0e1d48c016883858dd2dc574787524c6df84Brian Colonna        final boolean backupIsTimedOut = monitor.getFailedUnlockAttempts() >=
709ded0e1d48c016883858dd2dc574787524c6df84Brian Colonna                LockPatternUtils.FAILED_ATTEMPTS_BEFORE_TIMEOUT;
71cc4104fd71225ed092f16b11882d9a10084e34acBrian Colonna        return monitor.getMaxBiometricUnlockAttemptsReached() || backupIsTimedOut
72d95c659a1d621dfbdd892759419ffc089e248672Danielle Millett                || !monitor.isAlternateUnlockEnabled()
73d95c659a1d621dfbdd892759419ffc089e248672Danielle Millett                || monitor.getPhoneState() != TelephonyManager.CALL_STATE_IDLE;
74258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
75258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
76dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    SecurityMode getSecurityMode() {
77109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller        KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
78109f1fd80c90409c0d7f21d49989641dfdf2ad1bJim Miller        final IccCardConstants.State simState = updateMonitor.getSimState();
79258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        SecurityMode mode = SecurityMode.None;
80dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        if (simState == IccCardConstants.State.PIN_REQUIRED) {
81258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            mode = SecurityMode.SimPin;
8247df44aad773fb2a46d4c07e20278c7d8c0b16beJim Miller        } else if (simState == IccCardConstants.State.PUK_REQUIRED
8347df44aad773fb2a46d4c07e20278c7d8c0b16beJim Miller                && mLockPatternUtils.isPukUnlockScreenEnable()) {
84258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            mode = SecurityMode.SimPuk;
85dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        } else {
86258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            final int security = mLockPatternUtils.getKeyguardStoredPasswordQuality();
87258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            switch (security) {
88dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                case DevicePolicyManager.PASSWORD_QUALITY_NUMERIC:
8969bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                    mode = mLockPatternUtils.isLockPasswordEnabled() ?
9069bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                            SecurityMode.PIN : SecurityMode.None;
9169bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                    break;
92dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                case DevicePolicyManager.PASSWORD_QUALITY_ALPHABETIC:
93dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                case DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC:
94dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                case DevicePolicyManager.PASSWORD_QUALITY_COMPLEX:
95258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    mode = mLockPatternUtils.isLockPasswordEnabled() ?
96dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                            SecurityMode.Password : SecurityMode.None;
97258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    break;
98dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
99dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                case DevicePolicyManager.PASSWORD_QUALITY_SOMETHING:
100dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                case DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED:
101dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    if (mLockPatternUtils.isLockPatternEnabled()) {
102258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                        mode = mLockPatternUtils.isPermanentlyLocked() ?
103dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                            SecurityMode.Account : SecurityMode.Pattern;
104dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                    }
105258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    break;
106258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
107dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller                default:
108258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                    throw new IllegalStateException("Unknown unlock mode:" + mode);
109dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller            }
110dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller        }
111258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        return mode;
112dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
113dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller
114258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    /**
115258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * Some unlock methods can have an alternate, such as biometric unlocks (e.g. face unlock).
116258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * This function decides if an alternate unlock is available and returns it. Otherwise,
117258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * returns @param mode.
118258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     *
119258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * @param mode the mode we want the alternate for
120258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * @return alternate or the given mode
121258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     */
122258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    SecurityMode getAlternateFor(SecurityMode mode) {
1239ded0e1d48c016883858dd2dc574787524c6df84Brian Colonna        if (isBiometricUnlockEnabled() && !isBiometricUnlockSuppressed()
12469bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                && (mode == SecurityMode.Password
12569bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                        || mode == SecurityMode.PIN
12669bdee7c873c4a2295651efda2d0e79c515acc17Daniel Sandler                        || mode == SecurityMode.Pattern)) {
127258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            return SecurityMode.Biometric;
128258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
129258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        return mode; // no alternate, return what was given
130258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    }
131258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller
132258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller    /**
133258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * Some unlock methods can have a backup which gives the user another way to get into
134258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     * the device. This is currently only supported for Biometric and Pattern unlock.
135258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     *
1369ded0e1d48c016883858dd2dc574787524c6df84Brian Colonna     * @return backup method or current security mode
137258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller     */
13863f9b81795559443e0376985f8aaaa97a359ef94Jim Miller    SecurityMode getBackupSecurityMode(SecurityMode mode) {
139258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        switch(mode) {
140258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            case Biometric:
141258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                return getSecurityMode();
142258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller            case Pattern:
143258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller                return SecurityMode.Account;
144258341c377b6aa9f1bd29a9b507a97967e432dfeJim Miller        }
1459ded0e1d48c016883858dd2dc574787524c6df84Brian Colonna        return mode; // no backup, return current security mode
146dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller    }
147dcb3d84b82cc2448d04e73359a716581bfb657dbJim Miller}
148