1ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi/*
2ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi * Copyright (C) 2014 The Android Open Source Project
3ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi *
4ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi * Licensed under the Apache License, Version 2.0 (the "License");
5ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi * you may not use this file except in compliance with the License.
6ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi * You may obtain a copy of the License at
7ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi *
8ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi *      http://www.apache.org/licenses/LICENSE-2.0
9ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi *
10ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi * Unless required by applicable law or agreed to in writing, software
11ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi * distributed under the License is distributed on an "AS IS" BASIS,
12ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi * See the License for the specific language governing permissions and
14ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi * limitations under the License
15ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi */
16ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
17ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggipackage com.android.systemui.statusbar.phone;
18ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
19ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggiimport android.content.Context;
201d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniersimport android.os.Trace;
21ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
22ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggiimport com.android.internal.widget.LockPatternUtils;
23ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggiimport com.android.keyguard.KeyguardUpdateMonitor;
24ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggiimport com.android.keyguard.KeyguardUpdateMonitorCallback;
25ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
26ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggiimport java.util.ArrayList;
27ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
28ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi/**
29ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi * Caches whether the current unlock method is insecure, taking trust into account. This information
30ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi * might be a little bit out of date and should not be used for actual security decisions; it should
31ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi * be only used for visual indications.
32ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi */
33ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggipublic class UnlockMethodCache {
34ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
35ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    private static UnlockMethodCache sInstance;
36ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
37ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    private final LockPatternUtils mLockPatternUtils;
38ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
39ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    private final ArrayList<OnUnlockMethodChangedListener> mListeners = new ArrayList<>();
402231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    /** Whether the user configured a secure unlock method (PIN, password, etc.) */
412231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    private boolean mSecure;
422231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    /** Whether the unlock method is currently insecure (insecure method or trusted environment) */
43e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek    private boolean mCanSkipBouncer;
447861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    private boolean mTrustManaged;
454a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos    private boolean mFaceUnlockRunning;
46e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek    private boolean mTrusted;
47ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
48ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    private UnlockMethodCache(Context ctx) {
49ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        mLockPatternUtils = new LockPatternUtils(ctx);
50ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(ctx);
51ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        KeyguardUpdateMonitor.getInstance(ctx).registerCallback(mCallback);
522231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer        update(true /* updateAlways */);
53ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
54ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
55ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    public static UnlockMethodCache getInstance(Context context) {
56ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        if (sInstance == null) {
57ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi            sInstance = new UnlockMethodCache(context);
58ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        }
59ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        return sInstance;
60ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
61ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
62ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    /**
632231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer     * @return whether the user configured a secure unlock method like PIN, password, etc.
64ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi     */
652231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    public boolean isMethodSecure() {
662231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer        return mSecure;
672231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    }
682231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer
69e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek    public boolean isTrusted() {
70e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek        return mTrusted;
71e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek    }
72e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek
732231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    /**
74e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek     * @return whether the lockscreen is currently insecure, and the bouncer won't be shown
752231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer     */
76e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek    public boolean canSkipBouncer() {
77e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek        return mCanSkipBouncer;
78ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
79ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
80ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    public void addListener(OnUnlockMethodChangedListener listener) {
81ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        mListeners.add(listener);
82ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
83ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
84ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    public void removeListener(OnUnlockMethodChangedListener listener) {
85ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        mListeners.remove(listener);
86ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
87ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
882231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    private void update(boolean updateAlways) {
891d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers        Trace.beginSection("UnlockMethodCache#update");
90d6aa6cb0cc8c70a30434048e25e14643b1645755Adrian Roos        int user = KeyguardUpdateMonitor.getCurrentUser();
918150d2a2a12b38598fd55d8ae3c3b5662ec3520fAdrian Roos        boolean secure = mLockPatternUtils.isSecure(user);
92e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek        boolean canSkipBouncer = !secure ||  mKeyguardUpdateMonitor.getUserCanSkipBouncer(user);
937861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
94e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek        boolean trusted = mKeyguardUpdateMonitor.getUserHasTrust(user);
954a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos        boolean faceUnlockRunning = mKeyguardUpdateMonitor.isFaceUnlockRunning(user)
964a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos                && trustManaged;
97e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek        boolean changed = secure != mSecure || canSkipBouncer != mCanSkipBouncer ||
982231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer                trustManaged != mTrustManaged  || faceUnlockRunning != mFaceUnlockRunning;
99ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        if (changed || updateAlways) {
1002231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            mSecure = secure;
101e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek            mCanSkipBouncer = canSkipBouncer;
102e8bae6288bf0f241f0cea70f2c5e8294f930d4d8Selim Cinek            mTrusted = trusted;
1037861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            mTrustManaged = trustManaged;
1044a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos            mFaceUnlockRunning = faceUnlockRunning;
1052231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            notifyListeners();
106ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        }
1071d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers        Trace.endSection();
108ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
109ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
1102231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    private void notifyListeners() {
111ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        for (OnUnlockMethodChangedListener listener : mListeners) {
1122231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            listener.onUnlockMethodStateChanged();
113ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        }
114ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
115ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
116ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
117ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        @Override
118ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        public void onUserSwitchComplete(int userId) {
1192231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            update(false /* updateAlways */);
120ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        }
121ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
122ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        @Override
123ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        public void onTrustChanged(int userId) {
1242231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            update(false /* updateAlways */);
125ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        }
126ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
127ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        @Override
1287861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        public void onTrustManagedChanged(int userId) {
1292231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            update(false /* updateAlways */);
1307861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        }
1317861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos
1327861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        @Override
1330d210f6395072db4a4c53d4cb8fac4a59a3965b4Jorim Jaggi        public void onStartedWakingUp() {
1342231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            update(false /* updateAlways */);
135ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        }
136f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller
1377861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        @Override
13883eb6bb5d83d3994a3750b566a2109a049ab1388Jorim Jaggi        public void onFingerprintAuthenticated(int userId) {
1391d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers            Trace.beginSection("KeyguardUpdateMonitorCallback#onFingerprintAuthenticated");
1401fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek            if (!mKeyguardUpdateMonitor.isUnlockingWithFingerprintAllowed()) {
1411d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers                Trace.endSection();
1421fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek                return;
1431fcafc49ad34cb8f778862653d452ac0fe61461cSelim Cinek            }
1442231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            update(false /* updateAlways */);
1451d3967506e1cb3843d3bf758187ebc42d1c83485Nick Desaulniers            Trace.endSection();
146f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller        }
1474a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos
1484a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos        @Override
1494a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos        public void onFaceUnlockStateChanged(boolean running, int userId) {
1502231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            update(false /* updateAlways */);
1514a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos        }
15225b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi
15325b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi        @Override
1541de8bcb1e51917a301cab2ef7d276b4f9423d95fAdrian Roos        public void onStrongAuthStateChanged(int userId) {
15525b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi            update(false /* updateAlways */);
15625b4d4b280c6aa07656328bd9dd90977781d00e1Jorim Jaggi        }
157ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    };
158ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
1597861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    public boolean isTrustManaged() {
1607861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        return mTrustManaged;
1617861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    }
1627861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos
1634a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos    public boolean isFaceUnlockRunning() {
1644a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos        return mFaceUnlockRunning;
1654a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos    }
1664a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos
167ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    public static interface OnUnlockMethodChangedListener {
1682231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer        void onUnlockMethodStateChanged();
169ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
170ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi}
171