• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 package com.android.systemui.statusbar.phone;
18 
19 import android.app.admin.DevicePolicyManager;
20 import android.content.BroadcastReceiver;
21 import android.content.Context;
22 import android.content.Intent;
23 import android.content.IntentFilter;
24 import android.hardware.biometrics.BiometricSourceType;
25 import android.media.AudioManager;
26 import android.os.Build;
27 import android.os.Trace;
28 import android.telephony.TelephonyManager;
29 
30 import com.android.internal.telephony.TelephonyIntents;
31 import com.android.internal.widget.LockPatternUtils;
32 import com.android.keyguard.KeyguardUpdateMonitor;
33 import com.android.keyguard.KeyguardUpdateMonitorCallback;
34 
35 import java.util.ArrayList;
36 
37 /**
38  * Caches whether the current unlock method is insecure, taking trust into account. This information
39  * might be a little bit out of date and should not be used for actual security decisions; it should
40  * be only used for visual indications.
41  */
42 public class UnlockMethodCache {
43 
44     private static UnlockMethodCache sInstance;
45     private static final boolean DEBUG_AUTH_WITH_ADB = false;
46     private static final String AUTH_BROADCAST_KEY = "debug_trigger_auth";
47 
48     private final LockPatternUtils mLockPatternUtils;
49     private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
50     private final ArrayList<OnUnlockMethodChangedListener> mListeners = new ArrayList<>();
51     /** Whether the user configured a secure unlock method (PIN, password, etc.) */
52     private boolean mSecure;
53     /** Whether the unlock method is currently insecure (insecure method or trusted environment) */
54     private boolean mCanSkipBouncer;
55     private boolean mTrustManaged;
56     private boolean mTrusted;
57     private boolean mDebugUnlocked = false;
58 
UnlockMethodCache(Context ctx)59     private UnlockMethodCache(Context ctx) {
60         mLockPatternUtils = new LockPatternUtils(ctx);
61         mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(ctx);
62         KeyguardUpdateMonitor.getInstance(ctx).registerCallback(mCallback);
63         update(true /* updateAlways */);
64         if (Build.IS_DEBUGGABLE && DEBUG_AUTH_WITH_ADB) {
65             // Watch for interesting updates
66             final IntentFilter filter = new IntentFilter();
67             filter.addAction(AUTH_BROADCAST_KEY);
68             ctx.registerReceiver(new BroadcastReceiver() {
69                 @Override
70                 public void onReceive(Context context, Intent intent) {
71                     if (DEBUG_AUTH_WITH_ADB && AUTH_BROADCAST_KEY.equals(intent.getAction())) {
72                         mDebugUnlocked = !mDebugUnlocked;
73                         update(true /* updateAlways */);
74                     }
75                 }
76             }, filter, null, null);
77         }
78     }
79 
getInstance(Context context)80     public static UnlockMethodCache getInstance(Context context) {
81         if (sInstance == null) {
82             sInstance = new UnlockMethodCache(context);
83         }
84         return sInstance;
85     }
86 
87     /**
88      * @return whether the user configured a secure unlock method like PIN, password, etc.
89      */
isMethodSecure()90     public boolean isMethodSecure() {
91         return mSecure;
92     }
93 
isTrusted()94     public boolean isTrusted() {
95         return mTrusted;
96     }
97 
98     /**
99      * @return whether the lockscreen is currently insecure, and the bouncer won't be shown
100      */
canSkipBouncer()101     public boolean canSkipBouncer() {
102         return mCanSkipBouncer;
103     }
104 
addListener(OnUnlockMethodChangedListener listener)105     public void addListener(OnUnlockMethodChangedListener listener) {
106         mListeners.add(listener);
107     }
108 
removeListener(OnUnlockMethodChangedListener listener)109     public void removeListener(OnUnlockMethodChangedListener listener) {
110         mListeners.remove(listener);
111     }
112 
update(boolean updateAlways)113     private void update(boolean updateAlways) {
114         Trace.beginSection("UnlockMethodCache#update");
115         int user = KeyguardUpdateMonitor.getCurrentUser();
116         boolean secure = mLockPatternUtils.isSecure(user);
117         boolean canSkipBouncer = !secure || mKeyguardUpdateMonitor.getUserCanSkipBouncer(user)
118                 || (Build.IS_DEBUGGABLE && DEBUG_AUTH_WITH_ADB && mDebugUnlocked);
119         boolean trustManaged = mKeyguardUpdateMonitor.getUserTrustIsManaged(user);
120         boolean trusted = mKeyguardUpdateMonitor.getUserHasTrust(user);
121         boolean changed = secure != mSecure || canSkipBouncer != mCanSkipBouncer ||
122                 trustManaged != mTrustManaged;
123         if (changed || updateAlways) {
124             mSecure = secure;
125             mCanSkipBouncer = canSkipBouncer;
126             mTrusted = trusted;
127             mTrustManaged = trustManaged;
128             notifyListeners();
129         }
130         Trace.endSection();
131     }
132 
notifyListeners()133     private void notifyListeners() {
134         for (OnUnlockMethodChangedListener listener : mListeners) {
135             listener.onUnlockMethodStateChanged();
136         }
137     }
138 
139     private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
140         @Override
141         public void onUserSwitchComplete(int userId) {
142             update(false /* updateAlways */);
143         }
144 
145         @Override
146         public void onTrustChanged(int userId) {
147             update(false /* updateAlways */);
148         }
149 
150         @Override
151         public void onTrustManagedChanged(int userId) {
152             update(false /* updateAlways */);
153         }
154 
155         @Override
156         public void onStartedWakingUp() {
157             update(false /* updateAlways */);
158         }
159 
160         @Override
161         public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType) {
162             Trace.beginSection("KeyguardUpdateMonitorCallback#onBiometricAuthenticated");
163             if (!mKeyguardUpdateMonitor.isUnlockingWithBiometricAllowed()) {
164                 Trace.endSection();
165                 return;
166             }
167             update(false /* updateAlways */);
168             Trace.endSection();
169         }
170 
171         @Override
172         public void onFaceUnlockStateChanged(boolean running, int userId) {
173             update(false /* updateAlways */);
174         }
175 
176         @Override
177         public void onStrongAuthStateChanged(int userId) {
178             update(false /* updateAlways */);
179         }
180 
181         @Override
182         public void onScreenTurnedOff() {
183             update(false /* updateAlways */);
184         }
185 
186         @Override
187         public void onKeyguardVisibilityChanged(boolean showing) {
188             update(false /* updateAlways */);
189         }
190     };
191 
isTrustManaged()192     public boolean isTrustManaged() {
193         return mTrustManaged;
194     }
195 
196     public static interface OnUnlockMethodChangedListener {
onUnlockMethodStateChanged()197         void onUnlockMethodStateChanged();
198     }
199 }
200