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