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;
20ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
21ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggiimport com.android.internal.widget.LockPatternUtils;
22ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggiimport com.android.keyguard.KeyguardUpdateMonitor;
23ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggiimport com.android.keyguard.KeyguardUpdateMonitorCallback;
24ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
25ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggiimport java.util.ArrayList;
26ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
27ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi/**
28ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi * Caches whether the current unlock method is insecure, taking trust into account. This information
29ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi * might be a little bit out of date and should not be used for actual security decisions; it should
30ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi * be only used for visual indications.
31ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi */
32ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggipublic class UnlockMethodCache {
33ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
34ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    private static UnlockMethodCache sInstance;
35ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
36ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    private final LockPatternUtils mLockPatternUtils;
37ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
38ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    private final ArrayList<OnUnlockMethodChangedListener> mListeners = new ArrayList<>();
392231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    /** Whether the user configured a secure unlock method (PIN, password, etc.) */
402231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    private boolean mSecure;
412231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    /** Whether the unlock method is currently insecure (insecure method or trusted environment) */
422231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    private boolean mCurrentlyInsecure;
437861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    private boolean mTrustManaged;
444a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos    private boolean mFaceUnlockRunning;
45ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
46ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    private UnlockMethodCache(Context ctx) {
47ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        mLockPatternUtils = new LockPatternUtils(ctx);
48ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(ctx);
49ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        KeyguardUpdateMonitor.getInstance(ctx).registerCallback(mCallback);
502231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer        update(true /* updateAlways */);
51ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
52ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
53ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    public static UnlockMethodCache getInstance(Context context) {
54ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        if (sInstance == null) {
55ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi            sInstance = new UnlockMethodCache(context);
56ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        }
57ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        return sInstance;
58ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
59ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
60ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    /**
612231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer     * @return whether the user configured a secure unlock method like PIN, password, etc.
62ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi     */
632231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    public boolean isMethodSecure() {
642231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer        return mSecure;
652231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    }
662231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer
672231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    /**
682231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer     * @return whether the lockscreen is currently insecure, i. e. the bouncer won't be shown
692231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer     */
702231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    public boolean isCurrentlyInsecure() {
712231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer        return mCurrentlyInsecure;
72ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
73ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
74ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    public void addListener(OnUnlockMethodChangedListener listener) {
75ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        mListeners.add(listener);
76ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
77ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
78ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    public void removeListener(OnUnlockMethodChangedListener listener) {
79ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        mListeners.remove(listener);
80ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
81ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
822231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    private void update(boolean updateAlways) {
83ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        int user = mLockPatternUtils.getCurrentUser();
842231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer        boolean secure = mLockPatternUtils.isSecure();
852231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer        boolean currentlyInsecure = !secure ||  mKeyguardUpdateMonitor.getUserHasTrust(user);
867861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
874a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos        boolean faceUnlockRunning = mKeyguardUpdateMonitor.isFaceUnlockRunning(user)
884a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos                && trustManaged;
892231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer        boolean changed = secure != mSecure || currentlyInsecure != mCurrentlyInsecure ||
902231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer                trustManaged != mTrustManaged  || faceUnlockRunning != mFaceUnlockRunning;
91ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        if (changed || updateAlways) {
922231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            mSecure = secure;
932231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            mCurrentlyInsecure = currentlyInsecure;
947861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos            mTrustManaged = trustManaged;
954a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos            mFaceUnlockRunning = faceUnlockRunning;
962231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            notifyListeners();
97ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        }
98ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
99ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
1002231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer    private void notifyListeners() {
101ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        for (OnUnlockMethodChangedListener listener : mListeners) {
1022231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            listener.onUnlockMethodStateChanged();
103ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        }
104ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
105ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
106ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
107ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        @Override
108ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        public void onUserSwitchComplete(int userId) {
1092231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            update(false /* updateAlways */);
110ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        }
111ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
112ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        @Override
113ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        public void onTrustChanged(int userId) {
1142231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            update(false /* updateAlways */);
115ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        }
116ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
117ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        @Override
1187861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        public void onTrustManagedChanged(int userId) {
1192231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            update(false /* updateAlways */);
1207861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        }
1217861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos
1227861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        @Override
123ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        public void onScreenTurnedOn() {
1242231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            update(false /* updateAlways */);
125ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi        }
126f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller
1277861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        @Override
128f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller        public void onFingerprintRecognized(int userId) {
1292231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            update(false /* updateAlways */);
130f41fc9664febbdbf138e8540fd7a8281f1278eb1Jim Miller        }
1314a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos
1324a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos        @Override
1334a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos        public void onFaceUnlockStateChanged(boolean running, int userId) {
1342231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer            update(false /* updateAlways */);
1354a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos        }
136ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    };
137ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi
1387861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    public boolean isTrustManaged() {
1397861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos        return mTrustManaged;
1407861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos    }
1417861c663fd64af33ec2a4c5ad653c806dc8bd994Adrian Roos
1424a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos    public boolean isFaceUnlockRunning() {
1434a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos        return mFaceUnlockRunning;
1444a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos    }
1454a4101714dbd17bdabc67812e7e2449613b3f5bbAdrian Roos
146ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    public static interface OnUnlockMethodChangedListener {
1472231c6e1adefdb7636d9fe38a388f1b0660d30eaChristoph Studer        void onUnlockMethodStateChanged();
148ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi    }
149ecc798e6668046c2f67cf30c6ab1db2eba80cab1Jorim Jaggi}
150