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