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 21 import com.android.internal.widget.LockPatternUtils; 22 import com.android.keyguard.KeyguardUpdateMonitor; 23 import com.android.keyguard.KeyguardUpdateMonitorCallback; 24 25 import 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 */ 32 public 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 UnlockMethodCache(Context ctx)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 getInstance(Context context)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 */ isMethodSecure()64 public boolean isMethodSecure() { 65 return mSecure; 66 } 67 isTrusted()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 */ canSkipBouncer()75 public boolean canSkipBouncer() { 76 return mCanSkipBouncer; 77 } 78 addListener(OnUnlockMethodChangedListener listener)79 public void addListener(OnUnlockMethodChangedListener listener) { 80 mListeners.add(listener); 81 } 82 removeListener(OnUnlockMethodChangedListener listener)83 public void removeListener(OnUnlockMethodChangedListener listener) { 84 mListeners.remove(listener); 85 } 86 update(boolean updateAlways)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 notifyListeners()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 onStartedWakingUp() { 131 update(false /* updateAlways */); 132 } 133 134 @Override 135 public void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) { 136 if (!mKeyguardUpdateMonitor.isUnlockingWithFingerprintAllowed()) { 137 return; 138 } 139 update(false /* updateAlways */); 140 } 141 142 @Override 143 public void onFaceUnlockStateChanged(boolean running, int userId) { 144 update(false /* updateAlways */); 145 } 146 }; 147 isTrustManaged()148 public boolean isTrustManaged() { 149 return mTrustManaged; 150 } 151 isFaceUnlockRunning()152 public boolean isFaceUnlockRunning() { 153 return mFaceUnlockRunning; 154 } 155 156 public static interface OnUnlockMethodChangedListener { onUnlockMethodStateChanged()157 void onUnlockMethodStateChanged(); 158 } 159 } 160