UnlockMethodCache.java revision e8bae6288bf0f241f0cea70f2c5e8294f930d4d8
1/*
2 * Copyright (C) 2014 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 */
16
17package com.android.systemui.statusbar.phone;
18
19import android.content.Context;
20
21import com.android.internal.widget.LockPatternUtils;
22import com.android.keyguard.KeyguardUpdateMonitor;
23import com.android.keyguard.KeyguardUpdateMonitorCallback;
24
25import java.util.ArrayList;
26
27/**
28 * Caches whether the current unlock method is insecure, taking trust into account. This information
29 * might be a little bit out of date and should not be used for actual security decisions; it should
30 * be only used for visual indications.
31 */
32public class UnlockMethodCache {
33
34    private static UnlockMethodCache sInstance;
35
36    private final LockPatternUtils mLockPatternUtils;
37    private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
38    private final ArrayList<OnUnlockMethodChangedListener> mListeners = new ArrayList<>();
39    /** Whether the user configured a secure unlock method (PIN, password, etc.) */
40    private boolean mSecure;
41    /** Whether the unlock method is currently insecure (insecure method or trusted environment) */
42    private boolean mCanSkipBouncer;
43    private boolean mTrustManaged;
44    private boolean mFaceUnlockRunning;
45    private boolean mTrusted;
46
47    private UnlockMethodCache(Context ctx) {
48        mLockPatternUtils = new LockPatternUtils(ctx);
49        mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(ctx);
50        KeyguardUpdateMonitor.getInstance(ctx).registerCallback(mCallback);
51        update(true /* updateAlways */);
52    }
53
54    public static UnlockMethodCache getInstance(Context context) {
55        if (sInstance == null) {
56            sInstance = new UnlockMethodCache(context);
57        }
58        return sInstance;
59    }
60
61    /**
62     * @return whether the user configured a secure unlock method like PIN, password, etc.
63     */
64    public boolean isMethodSecure() {
65        return mSecure;
66    }
67
68    public boolean isTrusted() {
69        return mTrusted;
70    }
71
72    /**
73     * @return whether the lockscreen is currently insecure, and the bouncer won't be shown
74     */
75    public boolean canSkipBouncer() {
76        return mCanSkipBouncer;
77    }
78
79    public void addListener(OnUnlockMethodChangedListener listener) {
80        mListeners.add(listener);
81    }
82
83    public void removeListener(OnUnlockMethodChangedListener listener) {
84        mListeners.remove(listener);
85    }
86
87    private void update(boolean updateAlways) {
88        int user = KeyguardUpdateMonitor.getCurrentUser();
89        boolean secure = mLockPatternUtils.isSecure(user);
90        boolean canSkipBouncer = !secure ||  mKeyguardUpdateMonitor.getUserCanSkipBouncer(user);
91        boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
92        boolean trusted = mKeyguardUpdateMonitor.getUserHasTrust(user);
93        boolean faceUnlockRunning = mKeyguardUpdateMonitor.isFaceUnlockRunning(user)
94                && trustManaged;
95        boolean changed = secure != mSecure || canSkipBouncer != mCanSkipBouncer ||
96                trustManaged != mTrustManaged  || faceUnlockRunning != mFaceUnlockRunning;
97        if (changed || updateAlways) {
98            mSecure = secure;
99            mCanSkipBouncer = canSkipBouncer;
100            mTrusted = trusted;
101            mTrustManaged = trustManaged;
102            mFaceUnlockRunning = faceUnlockRunning;
103            notifyListeners();
104        }
105    }
106
107    private void notifyListeners() {
108        for (OnUnlockMethodChangedListener listener : mListeners) {
109            listener.onUnlockMethodStateChanged();
110        }
111    }
112
113    private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
114        @Override
115        public void onUserSwitchComplete(int userId) {
116            update(false /* updateAlways */);
117        }
118
119        @Override
120        public void onTrustChanged(int userId) {
121            update(false /* updateAlways */);
122        }
123
124        @Override
125        public void onTrustManagedChanged(int userId) {
126            update(false /* updateAlways */);
127        }
128
129        @Override
130        public void onScreenTurnedOn() {
131            update(false /* updateAlways */);
132        }
133
134        @Override
135        public void onFingerprintAuthenticated(int userId) {
136            update(false /* updateAlways */);
137        }
138
139        @Override
140        public void onFaceUnlockStateChanged(boolean running, int userId) {
141            update(false /* updateAlways */);
142        }
143    };
144
145    public boolean isTrustManaged() {
146        return mTrustManaged;
147    }
148
149    public boolean isFaceUnlockRunning() {
150        return mFaceUnlockRunning;
151    }
152
153    public static interface OnUnlockMethodChangedListener {
154        void onUnlockMethodStateChanged();
155    }
156}
157