blob: 26d3d86778e4a0779250fda720a9719678179a5c [file] [log] [blame]
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001/*
2 * Copyright (C) 2008 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
Jim Miller5ecd8112013-01-09 18:50:26 -080017package com.android.keyguard;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080018
Wale Ogunwale68278562017-09-23 17:13:55 -070019import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
20import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Jorim Jaggidadafd42016-09-30 07:20:25 -070021import static android.content.Intent.ACTION_USER_UNLOCKED;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070022import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
23import static android.os.BatteryManager.BATTERY_STATUS_FULL;
24import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
25import static android.os.BatteryManager.EXTRA_HEALTH;
26import static android.os.BatteryManager.EXTRA_LEVEL;
27import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
28import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
29import static android.os.BatteryManager.EXTRA_PLUGGED;
30import static android.os.BatteryManager.EXTRA_STATUS;
31
Adrian Roos30a2ae62018-04-25 19:09:50 +020032import android.annotation.AnyThread;
33import android.annotation.MainThread;
Jorim Jaggiccdfa932015-04-13 16:29:48 -070034import android.app.ActivityManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070035import android.app.ActivityTaskManager;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020036import android.app.AlarmManager;
Adrian Roos30a2ae62018-04-25 19:09:50 +020037import android.app.Instrumentation;
Jim Miller8f09fd22013-03-14 19:04:28 -070038import android.app.PendingIntent;
Sudheer Shanka2c4522c2016-08-27 20:53:28 -070039import android.app.UserSwitchObserver;
Jim Millerb0304762012-03-13 20:01:25 -070040import android.app.admin.DevicePolicyManager;
Adrian Roos46842d92014-03-27 14:58:03 +010041import android.app.trust.TrustManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080042import android.content.BroadcastReceiver;
Jorim Jaggi031f7952016-09-01 16:39:26 -070043import android.content.ComponentName;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080044import android.content.Context;
45import android.content.Intent;
46import android.content.IntentFilter;
Adrian Roosca8a2162017-08-17 19:00:58 +020047import android.content.pm.IPackageManager;
Jorim Jaggi031f7952016-09-01 16:39:26 -070048import android.content.pm.PackageManager;
49import android.content.pm.ResolveInfo;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080050import android.database.ContentObserver;
Kevin Chynb7b54a62018-09-28 18:48:12 -070051import android.hardware.biometrics.BiometricManager;
Kevin Chyn56233ab2018-09-20 17:10:57 -070052import android.hardware.biometrics.BiometricSourceType;
Kevin Chynb7b54a62018-09-28 18:48:12 -070053import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
Gilad Brettercb51b8b2018-03-22 17:04:51 +020054import android.hardware.face.FaceManager;
Jorim Jaggi86bed402015-08-20 18:20:02 -070055import android.hardware.fingerprint.FingerprintManager;
56import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
57import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
Jim Miller47088bb2009-11-24 00:40:16 -080058import android.media.AudioManager;
Jim Miller79a444a2011-02-15 15:02:11 -080059import android.os.BatteryManager;
Jim Miller9f0753f2015-03-23 23:59:22 -070060import android.os.CancellationSignal;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080061import android.os.Handler;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070062import android.os.IRemoteCallback;
Jason Monk7bb59302018-05-10 19:38:18 -070063import android.os.Looper;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080064import android.os.Message;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070065import android.os.RemoteException;
Adrian Roosca8a2162017-08-17 19:00:58 +020066import android.os.ServiceManager;
Nick Desaulniers1d396752016-07-25 15:05:33 -070067import android.os.Trace;
Amith Yamasanie8e93a12013-05-09 18:12:30 -070068import android.os.UserHandle;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070069import android.os.UserManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080070import android.provider.Settings;
Kevin Chyn36778ff2017-09-07 19:55:38 -070071import android.service.dreams.DreamService;
72import android.service.dreams.IDreamManager;
Etan Cohen47051d82015-07-06 16:19:04 -070073import android.telephony.ServiceState;
Jim Miller52a61332014-11-12 19:29:51 -080074import android.telephony.SubscriptionInfo;
Jim Miller52a61332014-11-12 19:29:51 -080075import android.telephony.SubscriptionManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -080076import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Jim Millerc23024d2010-02-24 15:37:00 -080077import android.telephony.TelephonyManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080078import android.util.Log;
Adrian Roos46842d92014-03-27 14:58:03 +010079import android.util.SparseBooleanArray;
80
Lucas Dupin7517b5d2017-08-22 12:51:25 -070081import com.android.internal.annotations.VisibleForTesting;
Jorim Jaggi86bed402015-08-20 18:20:02 -070082import com.android.internal.telephony.IccCardConstants;
83import com.android.internal.telephony.IccCardConstants.State;
84import com.android.internal.telephony.PhoneConstants;
85import com.android.internal.telephony.TelephonyIntents;
Adrian Roos30a2ae62018-04-25 19:09:50 +020086import com.android.internal.util.Preconditions;
Adrian Roosb5e47222015-08-14 15:53:06 -070087import com.android.internal.widget.LockPatternUtils;
Bill Linef81cbd2018-07-05 17:48:49 +080088import com.android.settingslib.WirelessUtils;
Winson Chung2cf6ad82017-11-09 17:36:59 -080089import com.android.systemui.shared.system.ActivityManagerWrapper;
Winson Chung67f5c8b2018-09-24 12:09:19 -070090import com.android.systemui.shared.system.TaskStackChangeListener;
Kevin Chyn1123ba72018-10-26 10:34:06 -070091
Kevin Chyn36778ff2017-09-07 19:55:38 -070092import com.google.android.collect.Lists;
93
Jason Monkab525272015-07-13 17:02:49 -040094import java.io.FileDescriptor;
95import java.io.PrintWriter;
Jim Millerdcb3d842012-08-23 19:18:12 -070096import java.lang.ref.WeakReference;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080097import java.util.ArrayList;
Jim Miller52a61332014-11-12 19:29:51 -080098import java.util.HashMap;
99import java.util.List;
100import java.util.Map.Entry;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500101import java.util.TimeZone;
Lucas Dupin3d053532019-01-29 12:35:22 -0800102import java.util.function.Consumer;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800103
104/**
105 * Watches for updates that may be interesting to the keyguard, and provides
106 * the up to date information as well as a registration for callbacks that care
107 * to be updated.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800108 */
Adrian Roos46842d92014-03-27 14:58:03 +0100109public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800110
Jim Millerbbf1a742012-07-17 18:30:30 -0700111 private static final String TAG = "KeyguardUpdateMonitor";
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100112 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller52a61332014-11-12 19:29:51 -0800113 private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700114 private static final boolean DEBUG_FACE = true;
Jim Millerbbf1a742012-07-17 18:30:30 -0700115 private static final int LOW_BATTERY_THRESHOLD = 20;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800116
Jorim Jaggie7b12522014-08-06 16:41:21 +0200117 private static final String ACTION_FACE_UNLOCK_STARTED
118 = "com.android.facelock.FACE_UNLOCK_STARTED";
119 private static final String ACTION_FACE_UNLOCK_STOPPED
120 = "com.android.facelock.FACE_UNLOCK_STOPPED";
121
Jim Millerbbf1a742012-07-17 18:30:30 -0700122 // Callback messages
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800123 private static final int MSG_TIME_UPDATE = 301;
124 private static final int MSG_BATTERY_UPDATE = 302;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800125 private static final int MSG_SIM_STATE_CHANGE = 304;
Jim Miller47088bb2009-11-24 00:40:16 -0800126 private static final int MSG_RINGER_MODE_CHANGED = 305;
Jim Millerc23024d2010-02-24 15:37:00 -0800127 private static final int MSG_PHONE_STATE_CHANGED = 306;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700128 private static final int MSG_DEVICE_PROVISIONED = 308;
Jim Miller57375342012-09-09 15:20:31 -0700129 private static final int MSG_DPM_STATE_CHANGED = 309;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500130 private static final int MSG_USER_SWITCHING = 310;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700131 private static final int MSG_KEYGUARD_RESET = 312;
Jim Millerf41fc962014-06-18 16:33:51 -0700132 private static final int MSG_BOOT_COMPLETED = 313;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500133 private static final int MSG_USER_SWITCH_COMPLETE = 314;
Jim Millerf41fc962014-06-18 16:33:51 -0700134 private static final int MSG_USER_INFO_CHANGED = 317;
135 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700136 private static final int MSG_STARTED_WAKING_UP = 319;
137 private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700138 private static final int MSG_STARTED_GOING_TO_SLEEP = 321;
Adrian Roosb6011622014-05-14 15:52:53 +0200139 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700140 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
141 private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
Jason Monk052082c2015-06-11 11:35:23 -0400142 private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
Etan Cohen47051d82015-07-06 16:19:04 -0700143 private static final int MSG_SERVICE_STATE_CHANGE = 330;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700144 private static final int MSG_SCREEN_TURNED_ON = 331;
145 private static final int MSG_SCREEN_TURNED_OFF = 332;
Selim Cinek99415392016-09-09 14:58:41 -0700146 private static final int MSG_DREAMING_STATE_CHANGED = 333;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700147 private static final int MSG_USER_UNLOCKED = 334;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700148 private static final int MSG_ASSISTANT_STACK_CHANGED = 335;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200149 private static final int MSG_BIOMETRIC_AUTHENTICATION_CONTINUE = 336;
Alex Chauff7653d2018-02-01 17:18:08 +0000150 private static final int MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED = 337;
Bill Linef81cbd2018-07-05 17:48:49 +0800151 private static final int MSG_TELEPHONY_CAPABLE = 338;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500152 private static final int MSG_TIMEZONE_UPDATE = 339;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800153
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200154 /** Biometric authentication state: Not listening. */
155 private static final int BIOMETRIC_STATE_STOPPED = 0;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700156
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200157 /** Biometric authentication state: Listening. */
158 private static final int BIOMETRIC_STATE_RUNNING = 1;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700159
160 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200161 * Biometric authentication: Cancelling and waiting for the relevant biometric service to
Jorim Jaggi86bed402015-08-20 18:20:02 -0700162 * send us the confirmation that cancellation has happened.
163 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200164 private static final int BIOMETRIC_STATE_CANCELLING = 2;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700165
166 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200167 * Biometric state: During cancelling we got another request to start listening, so when we
Jorim Jaggi86bed402015-08-20 18:20:02 -0700168 * receive the cancellation done signal, we should start listening again.
169 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200170 private static final int BIOMETRIC_STATE_CANCELLING_RESTARTING = 3;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700171
Lucas Dupin51996bb2019-05-16 17:56:43 -0700172 private static final int BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED = -1;
173 public static final int BIOMETRIC_HELP_FACE_NOT_RECOGNIZED = -2;
174
Adrian Roos0c859ae2015-11-23 16:47:50 -0800175 private static final int DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT = 5000000;
176
Jorim Jaggi031f7952016-09-01 16:39:26 -0700177 private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName(
178 "com.android.settings", "com.android.settings.FallbackHome");
179
Adrian Roosca8a2162017-08-17 19:00:58 +0200180
181 /**
182 * If true, the system is in the half-boot-to-decryption-screen state.
183 * Prudently disable lockscreen.
184 */
185 public static final boolean CORE_APPS_ONLY;
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700186
Adrian Roosca8a2162017-08-17 19:00:58 +0200187 static {
188 try {
189 CORE_APPS_ONLY = IPackageManager.Stub.asInterface(
190 ServiceManager.getService("package")).isOnlyCoreApps();
191 } catch (RemoteException e) {
192 throw e.rethrowFromSystemServer();
193 }
194 }
195
Jim Millerdcb3d842012-08-23 19:18:12 -0700196 private static KeyguardUpdateMonitor sInstance;
197
Jim Millerbbf1a742012-07-17 18:30:30 -0700198 private final Context mContext;
Kevin Chynfdfd2d32019-03-01 14:52:15 -0800199 private final boolean mIsPrimaryUser;
Jim Miller52a61332014-11-12 19:29:51 -0800200 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
Etan Cohen47051d82015-07-06 16:19:04 -0700201 HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700202
Jim Millerbbf1a742012-07-17 18:30:30 -0700203 private int mRingMode;
204 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400205 private boolean mKeyguardIsVisible;
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700206 private boolean mKeyguardGoingAway;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700207 private boolean mGoingToSleep;
Adrian Roosb6011622014-05-14 15:52:53 +0200208 private boolean mBouncer;
Lucas Dupine0516d52019-02-05 17:54:06 -0500209 private boolean mAuthInterruptActive;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800210 private boolean mBootCompleted;
Jorim Jaggi031f7952016-09-01 16:39:26 -0700211 private boolean mNeedsSlowUnlockTransition;
Jorim Jaggid11d1a92016-08-16 16:02:32 -0700212 private boolean mHasLockscreenWallpaper;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700213 private boolean mAssistantVisible;
214 private boolean mKeyguardOccluded;
Bill Linef81cbd2018-07-05 17:48:49 +0800215 @VisibleForTesting
216 protected boolean mTelephonyCapable;
Jim Millerbbf1a742012-07-17 18:30:30 -0700217
Jim Millerdcb3d842012-08-23 19:18:12 -0700218 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700219 private boolean mDeviceProvisioned;
220
Jim Millerdcb3d842012-08-23 19:18:12 -0700221 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700222 private BatteryStatus mBatteryStatus;
223
Lucas Dupin3d053532019-01-29 12:35:22 -0800224 @VisibleForTesting
225 protected StrongAuthTracker mStrongAuthTracker;
Jim Millerbbf1a742012-07-17 18:30:30 -0700226
Jim Miller6212cc02012-09-05 17:35:31 -0700227 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700228 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800229 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700230
Brian Colonnaa5239892013-04-15 11:45:40 -0400231 private boolean mSwitchingUser;
232
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700233 private boolean mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -0700234 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800235 private SubscriptionManager mSubscriptionManager;
236 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700237 private TrustManager mTrustManager;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700238 private UserManager mUserManager;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200239 private int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
240 private int mFaceRunningState = BIOMETRIC_STATE_STOPPED;
Michal Karpinskic52f8672016-11-18 11:32:45 +0000241 private LockPatternUtils mLockPatternUtils;
Kevin Chyn36778ff2017-09-07 19:55:38 -0700242 private final IDreamManager mDreamManager;
243 private boolean mIsDreaming;
Alex Chauff7653d2018-02-01 17:18:08 +0000244 private final DevicePolicyManager mDevicePolicyManager;
245 private boolean mLogoutEnabled;
Lucas Dupinca88e5f2019-05-14 16:11:08 -0700246 // If the user long pressed the lock icon, disabling face auth for the current session.
247 private boolean mLockIconPressed;
Jim Miller20daffd2013-10-07 14:59:53 -0700248
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700249 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200250 * Short delay before restarting biometric authentication after a successful try
251 * This should be slightly longer than the time between on<biometric>Authenticated
252 * (e.g. onFingerprintAuthenticated) and setKeyguardGoingAway(true).
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700253 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200254 private static final int BIOMETRIC_CONTINUE_DELAY_MS = 500;
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700255
Kevin Chyn0c45b072017-04-24 16:27:11 -0700256 // If FP daemon dies, keyguard should retry after a short delay
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200257 private int mHardwareFingerprintUnavailableRetryCount = 0;
258 private int mHardwareFaceUnavailableRetryCount = 0;
Kevin Chyn0c45b072017-04-24 16:27:11 -0700259 private static final int HW_UNAVAILABLE_TIMEOUT = 3000; // ms
260 private static final int HW_UNAVAILABLE_RETRY_MAX = 3;
261
Jason Monk7bb59302018-05-10 19:38:18 -0700262 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700263 @Override
264 public void handleMessage(Message msg) {
265 switch (msg.what) {
266 case MSG_TIME_UPDATE:
267 handleTimeUpdate();
268 break;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500269 case MSG_TIMEZONE_UPDATE:
270 handleTimeZoneUpdate((String) msg.obj);
271 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700272 case MSG_BATTERY_UPDATE:
273 handleBatteryUpdate((BatteryStatus) msg.obj);
274 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700275 case MSG_SIM_STATE_CHANGE:
Jim Miller52a61332014-11-12 19:29:51 -0800276 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700277 break;
278 case MSG_RINGER_MODE_CHANGED:
279 handleRingerModeChange(msg.arg1);
280 break;
281 case MSG_PHONE_STATE_CHANGED:
Adrian Roosb6011622014-05-14 15:52:53 +0200282 handlePhoneStateChanged((String) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700283 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700284 case MSG_DEVICE_PROVISIONED:
285 handleDeviceProvisioned();
286 break;
287 case MSG_DPM_STATE_CHANGED:
288 handleDevicePolicyManagerStateChanged();
289 break;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500290 case MSG_USER_SWITCHING:
Adrian Roosb6011622014-05-14 15:52:53 +0200291 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
Chris Wrenf41c61b2012-11-29 15:19:54 -0500292 break;
293 case MSG_USER_SWITCH_COMPLETE:
294 handleUserSwitchComplete(msg.arg1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700295 break;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700296 case MSG_KEYGUARD_RESET:
297 handleKeyguardReset();
298 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200299 case MSG_KEYGUARD_BOUNCER_CHANGED:
300 handleKeyguardBouncerChanged(msg.arg1);
301 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800302 case MSG_BOOT_COMPLETED:
303 handleBootCompleted();
304 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700305 case MSG_USER_INFO_CHANGED:
306 handleUserInfoChanged(msg.arg1);
307 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400308 case MSG_REPORT_EMERGENCY_CALL_ACTION:
309 handleReportEmergencyCallAction();
310 break;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700311 case MSG_STARTED_GOING_TO_SLEEP:
312 handleStartedGoingToSleep(msg.arg1);
313 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700314 case MSG_FINISHED_GOING_TO_SLEEP:
315 handleFinishedGoingToSleep(msg.arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700316 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700317 case MSG_STARTED_WAKING_UP:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700318 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_STARTED_WAKING_UP");
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700319 handleStartedWakingUp();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700320 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -0700321 break;
Jorim Jaggie7b12522014-08-06 16:41:21 +0200322 case MSG_FACE_UNLOCK_STATE_CHANGED:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700323 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_FACE_UNLOCK_STATE_CHANGED");
Adrian Roos4a410172014-08-20 17:41:44 +0200324 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
Nick Desaulniers1d396752016-07-25 15:05:33 -0700325 Trace.endSection();
Jorim Jaggie7b12522014-08-06 16:41:21 +0200326 break;
Jim Miller52a61332014-11-12 19:29:51 -0800327 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
328 handleSimSubscriptionInfoChanged();
329 break;
Jason Monk052082c2015-06-11 11:35:23 -0400330 case MSG_AIRPLANE_MODE_CHANGED:
331 handleAirplaneModeChanged();
332 break;
Etan Cohen47051d82015-07-06 16:19:04 -0700333 case MSG_SERVICE_STATE_CHANGE:
Bonian Chena7e9e8c2019-06-02 23:59:31 +0000334 handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
Etan Cohen47051d82015-07-06 16:19:04 -0700335 break;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700336 case MSG_SCREEN_TURNED_ON:
337 handleScreenTurnedOn();
338 break;
339 case MSG_SCREEN_TURNED_OFF:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700340 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_SCREEN_TURNED_ON");
Jorim Jaggif1518da2015-07-30 11:56:36 -0700341 handleScreenTurnedOff();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700342 Trace.endSection();
Jorim Jaggif1518da2015-07-30 11:56:36 -0700343 break;
Selim Cinek99415392016-09-09 14:58:41 -0700344 case MSG_DREAMING_STATE_CHANGED:
345 handleDreamingStateChanged(msg.arg1);
346 break;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700347 case MSG_USER_UNLOCKED:
348 handleUserUnlocked();
349 break;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700350 case MSG_ASSISTANT_STACK_CHANGED:
Lucas Dupin3d053532019-01-29 12:35:22 -0800351 setAssistantVisible((boolean) msg.obj);
Kevin Chyn2fefd462017-04-28 12:18:19 -0700352 break;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200353 case MSG_BIOMETRIC_AUTHENTICATION_CONTINUE:
354 updateBiometricListeningState();
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700355 break;
Alex Chauff7653d2018-02-01 17:18:08 +0000356 case MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED:
357 updateLogoutEnabled();
358 break;
Bill Linef81cbd2018-07-05 17:48:49 +0800359 case MSG_TELEPHONY_CAPABLE:
Lucas Dupin3d053532019-01-29 12:35:22 -0800360 updateTelephonyCapable((boolean) msg.obj);
Bill Linef81cbd2018-07-05 17:48:49 +0800361 break;
Jason Monk7bb59302018-05-10 19:38:18 -0700362 default:
363 super.handleMessage(msg);
364 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700365 }
366 }
367 };
368
Kevin Chynb7b54a62018-09-28 18:48:12 -0700369 private boolean mFaceSettingEnabledForUser;
370 private BiometricManager mBiometricManager;
371 private IBiometricEnabledOnKeyguardCallback mBiometricEnabledCallback =
372 new IBiometricEnabledOnKeyguardCallback.Stub() {
373 @Override
374 public void onChanged(BiometricSourceType type, boolean enabled) throws RemoteException {
375 if (type == BiometricSourceType.FACE) {
376 mFaceSettingEnabledForUser = enabled;
Kevin Chyn1e043d472019-03-11 14:48:17 -0700377 updateFaceListeningState();
Kevin Chynb7b54a62018-09-28 18:48:12 -0700378 }
379 }
380 };
381
Wink Savilled09c4ca2014-11-22 10:08:16 -0800382 private OnSubscriptionsChangedListener mSubscriptionListener =
383 new OnSubscriptionsChangedListener() {
Jim Miller52a61332014-11-12 19:29:51 -0800384 @Override
Wink Savilled09c4ca2014-11-22 10:08:16 -0800385 public void onSubscriptionsChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800386 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
387 }
388 };
389
Adrian Roos46842d92014-03-27 14:58:03 +0100390 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200391 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Jim Miller9f0753f2015-03-23 23:59:22 -0700392 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200393 private SparseBooleanArray mUserFaceAuthenticated = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200394 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100395
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700396 private static int sCurrentUser;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200397 private Runnable mUpdateBiometricListeningState = this::updateBiometricListeningState;
Adrian Roos30a2ae62018-04-25 19:09:50 +0200398 private static boolean sDisableHandlerCheckForTesting;
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700399
400 public synchronized static void setCurrentUser(int currentUser) {
401 sCurrentUser = currentUser;
402 }
403
404 public synchronized static int getCurrentUser() {
405 return sCurrentUser;
406 }
407
Adrian Roos46842d92014-03-27 14:58:03 +0100408 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700409 public void onTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200410 checkIsHandlerThread();
Adrian Roos46842d92014-03-27 14:58:03 +0100411 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200412 for (int i = 0; i < mCallbacks.size(); i++) {
413 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
414 if (cb != null) {
415 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700416 if (enabled && flags != 0) {
417 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200418 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200419 }
420 }
Adrian Roos46842d92014-03-27 14:58:03 +0100421 }
422
Lucas Dupinef886542018-01-03 16:03:07 -0800423 @Override
424 public void onTrustError(CharSequence message) {
425 dispatchErrorMessage(message);
426 }
427
Adrian Roos30a2ae62018-04-25 19:09:50 +0200428 private void handleSimSubscriptionInfoChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800429 if (DEBUG_SIM_STATES) {
430 Log.v(TAG, "onSubscriptionInfoChanged()");
Wink Savilled09c4ca2014-11-22 10:08:16 -0800431 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
432 if (sil != null) {
433 for (SubscriptionInfo subInfo : sil) {
434 Log.v(TAG, "SubInfo:" + subInfo);
435 }
436 } else {
437 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800438 }
439 }
440 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
441
442 // Hack level over 9000: Because the subscription id is not yet valid when we see the
443 // first update in handleSimStateChange, we need to force refresh all all SIM states
444 // so the subscription id for them is consistent.
Richard Choue0381b82018-04-24 03:48:59 +0000445 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
446 for (int i = 0; i < subscriptionInfos.size(); i++) {
447 SubscriptionInfo info = subscriptionInfos.get(i);
448 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
449 if (changed) {
450 changedSubscriptions.add(info);
451 }
452 }
453 for (int i = 0; i < changedSubscriptions.size(); i++) {
454 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800455 for (int j = 0; j < mCallbacks.size(); j++) {
456 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
457 if (cb != null) {
458 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
459 }
460 }
461 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500462 for (int j = 0; j < mCallbacks.size(); j++) {
463 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
464 if (cb != null) {
465 cb.onRefreshCarrierInfo();
466 }
467 }
Jim Miller52a61332014-11-12 19:29:51 -0800468 }
469
Jason Monk052082c2015-06-11 11:35:23 -0400470 private void handleAirplaneModeChanged() {
471 for (int j = 0; j < mCallbacks.size(); j++) {
472 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
473 if (cb != null) {
474 cb.onRefreshCarrierInfo();
475 }
476 }
477 }
478
Wink Savilled09c4ca2014-11-22 10:08:16 -0800479 /** @return List of SubscriptionInfo records, maybe empty but never null */
Adrian Roos316bf542016-08-23 17:53:07 +0200480 public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800481 List<SubscriptionInfo> sil = mSubscriptionInfo;
482 if (sil == null || forceReload) {
483 sil = mSubscriptionManager.getActiveSubscriptionInfoList();
484 }
485 if (sil == null) {
486 // getActiveSubscriptionInfoList was null callers expect an empty list.
487 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
488 } else {
489 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800490 }
491 return mSubscriptionInfo;
492 }
493
Adrian Roos7861c662014-07-25 15:37:28 +0200494 @Override
495 public void onTrustManagedChanged(boolean managed, int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200496 checkIsHandlerThread();
Adrian Roos7861c662014-07-25 15:37:28 +0200497 mUserTrustIsManaged.put(userId, managed);
498
499 for (int i = 0; i < mCallbacks.size(); i++) {
500 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
501 if (cb != null) {
502 cb.onTrustManagedChanged(userId);
503 }
504 }
505 }
506
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700507 /**
508 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is goingAway
509 * @param goingAway
510 */
511 public void setKeyguardGoingAway(boolean goingAway) {
512 mKeyguardGoingAway = goingAway;
Kevin Chyne22f1342017-09-26 10:03:38 -0700513 updateFingerprintListeningState();
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700514 }
515
Kevin Chyn2fefd462017-04-28 12:18:19 -0700516 /**
517 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is occluded
518 * @param occluded
519 */
520 public void setKeyguardOccluded(boolean occluded) {
521 mKeyguardOccluded = occluded;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200522 updateBiometricListeningState();
Kevin Chyn2fefd462017-04-28 12:18:19 -0700523 }
524
Kevin Chyn36778ff2017-09-07 19:55:38 -0700525 /**
526 * @return a cached version of DreamManager.isDreaming()
527 */
528 public boolean isDreaming() {
529 return mIsDreaming;
530 }
531
532 /**
533 * If the device is dreaming, awakens the device
534 */
535 public void awakenFromDream() {
536 if (mIsDreaming && mDreamManager != null) {
537 try {
538 mDreamManager.awaken();
539 } catch (RemoteException e) {
540 Log.e(TAG, "Unable to awaken from dream");
541 }
542 }
543 }
544
Lucas Dupin3d053532019-01-29 12:35:22 -0800545 @VisibleForTesting
546 protected void onFingerprintAuthenticated(int userId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700547 Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
Jim Miller9f0753f2015-03-23 23:59:22 -0700548 mUserFingerprintAuthenticated.put(userId, true);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700549 // Update/refresh trust state only if user can skip bouncer
550 if (getUserCanSkipBouncer(userId)) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200551 mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FINGERPRINT);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700552 }
Kevin Chyn625a0142017-04-10 14:53:59 -0700553 // Don't send cancel if authentication succeeds
554 mFingerprintCancelSignal = null;
Jim Millerf41fc962014-06-18 16:33:51 -0700555 for (int i = 0; i < mCallbacks.size(); i++) {
556 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
557 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200558 cb.onBiometricAuthenticated(userId, BiometricSourceType.FINGERPRINT);
Jim Millerf41fc962014-06-18 16:33:51 -0700559 }
560 }
Kevin Chyn2fefd462017-04-28 12:18:19 -0700561
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200562 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE),
563 BIOMETRIC_CONTINUE_DELAY_MS);
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700564
Kevin Chyn2fefd462017-04-28 12:18:19 -0700565 // Only authenticate fingerprint once when assistant is visible
566 mAssistantVisible = false;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700567
Nick Desaulniers1d396752016-07-25 15:05:33 -0700568 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700569 }
570
Jim Millerce7eb6d2015-04-03 19:29:13 -0700571 private void handleFingerprintAuthFailed() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700572 for (int i = 0; i < mCallbacks.size(); i++) {
573 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
574 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200575 cb.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700576 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700577 }
Lucas Dupin51996bb2019-05-16 17:56:43 -0700578 handleFingerprintHelp(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
579 mContext.getString(R.string.kg_fingerprint_not_recognized));
Jim Millerce7eb6d2015-04-03 19:29:13 -0700580 }
Jim Millerf41fc962014-06-18 16:33:51 -0700581
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700582 private void handleFingerprintAcquired(int acquireInfo) {
583 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
584 return;
585 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700586 for (int i = 0; i < mCallbacks.size(); i++) {
587 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
588 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200589 cb.onBiometricAcquired(BiometricSourceType.FINGERPRINT);
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700590 }
591 }
592 }
593
Jim Miller837fa7e2016-08-08 20:16:22 -0700594 private void handleFingerprintAuthenticated(int authUserId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700595 Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
Jim Millerf41fc962014-06-18 16:33:51 -0700596 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700597 final int userId;
598 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800599 userId = ActivityManager.getService().getCurrentUser().id;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700600 } catch (RemoteException e) {
601 Log.e(TAG, "Failed to get current user id: ", e);
602 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700603 }
Jim Miller837fa7e2016-08-08 20:16:22 -0700604 if (userId != authUserId) {
605 Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId);
606 return;
607 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700608 if (isFingerprintDisabled(userId)) {
609 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
610 return;
611 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700612 onFingerprintAuthenticated(userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700613 } finally {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200614 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Jim Millerf41fc962014-06-18 16:33:51 -0700615 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700616 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700617 }
618
Jim Miller9f0753f2015-03-23 23:59:22 -0700619 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700620 for (int i = 0; i < mCallbacks.size(); i++) {
621 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
622 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200623 cb.onBiometricHelp(msgId, helpString, BiometricSourceType.FINGERPRINT);
Jim Miller9f0753f2015-03-23 23:59:22 -0700624 }
625 }
626 }
627
Kevin Chyn0c45b072017-04-24 16:27:11 -0700628 private Runnable mRetryFingerprintAuthentication = new Runnable() {
629 @Override
630 public void run() {
631 Log.w(TAG, "Retrying fingerprint after HW unavailable, attempt " +
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200632 mHardwareFingerprintUnavailableRetryCount);
Kevin Chyn0c45b072017-04-24 16:27:11 -0700633 updateFingerprintListeningState();
634 }
635 };
636
Jim Miller9f0753f2015-03-23 23:59:22 -0700637 private void handleFingerprintError(int msgId, String errString) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700638 if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200639 && mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
640 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Kevin Chyn1123ba72018-10-26 10:34:06 -0700641 updateFingerprintListeningState();
Jorim Jaggi86bed402015-08-20 18:20:02 -0700642 } else {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200643 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Jorim Jaggi86bed402015-08-20 18:20:02 -0700644 }
Kevin Chyn0c45b072017-04-24 16:27:11 -0700645
646 if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200647 if (mHardwareFingerprintUnavailableRetryCount < HW_UNAVAILABLE_RETRY_MAX) {
648 mHardwareFingerprintUnavailableRetryCount++;
Kevin Chyn0c45b072017-04-24 16:27:11 -0700649 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
650 mHandler.postDelayed(mRetryFingerprintAuthentication, HW_UNAVAILABLE_TIMEOUT);
651 }
652 }
653
Kevin Chyndf9d33e2017-05-03 21:40:12 -0700654 if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
655 mLockPatternUtils.requireStrongAuth(
656 LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
657 getCurrentUser());
658 }
659
Jim Miller9f0753f2015-03-23 23:59:22 -0700660 for (int i = 0; i < mCallbacks.size(); i++) {
661 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
662 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200663 cb.onBiometricError(msgId, errString, BiometricSourceType.FINGERPRINT);
Jim Millerf41fc962014-06-18 16:33:51 -0700664 }
665 }
666 }
667
Jorim Jaggi3a464782015-08-28 16:59:13 -0700668 private void handleFingerprintLockoutReset() {
669 updateFingerprintListeningState();
670 }
671
Jorim Jaggi86bed402015-08-20 18:20:02 -0700672 private void setFingerprintRunningState(int fingerprintRunningState) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200673 boolean wasRunning = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
674 boolean isRunning = fingerprintRunningState == BIOMETRIC_STATE_RUNNING;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700675 mFingerprintRunningState = fingerprintRunningState;
Kevin Chynb4514d22019-04-15 13:47:25 -0700676 Log.d(TAG, "fingerprintRunningState: " + mFingerprintRunningState);
Jorim Jaggi86bed402015-08-20 18:20:02 -0700677 // Clients of KeyguardUpdateMonitor don't care about the internal state about the
Kevin Chynb4514d22019-04-15 13:47:25 -0700678 // asynchronousness of the cancel cycle. So only notify them if the actually running state
Jorim Jaggi86bed402015-08-20 18:20:02 -0700679 // has changed.
680 if (wasRunning != isRunning) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700681 notifyFingerprintRunningStateChanged();
682 }
683 }
684
685 private void notifyFingerprintRunningStateChanged() {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200686 checkIsHandlerThread();
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700687 for (int i = 0; i < mCallbacks.size(); i++) {
688 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
689 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200690 cb.onBiometricRunningStateChanged(isFingerprintDetectionRunning(),
691 BiometricSourceType.FINGERPRINT);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700692 }
693 }
694 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200695
Lucas Dupin3d053532019-01-29 12:35:22 -0800696 @VisibleForTesting
697 protected void onFaceAuthenticated(int userId) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200698 Trace.beginSection("KeyGuardUpdateMonitor#onFaceAuthenticated");
699 mUserFaceAuthenticated.put(userId, true);
700 // Update/refresh trust state only if user can skip bouncer
701 if (getUserCanSkipBouncer(userId)) {
702 mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FACE);
703 }
704 // Don't send cancel if authentication succeeds
705 mFaceCancelSignal = null;
706 for (int i = 0; i < mCallbacks.size(); i++) {
707 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
708 if (cb != null) {
709 cb.onBiometricAuthenticated(userId,
710 BiometricSourceType.FACE);
711 }
712 }
713
714 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE),
715 BIOMETRIC_CONTINUE_DELAY_MS);
716
717 // Only authenticate face once when assistant is visible
718 mAssistantVisible = false;
719
720 Trace.endSection();
721 }
722
723 private void handleFaceAuthFailed() {
Lucas Dupin38314812019-02-15 14:10:55 -0800724 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200725 for (int i = 0; i < mCallbacks.size(); i++) {
726 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
727 if (cb != null) {
728 cb.onBiometricAuthFailed(BiometricSourceType.FACE);
729 }
730 }
Lucas Dupin51996bb2019-05-16 17:56:43 -0700731 handleFaceHelp(BIOMETRIC_HELP_FACE_NOT_RECOGNIZED,
732 mContext.getString(R.string.kg_face_not_recognized));
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200733 }
734
735 private void handleFaceAcquired(int acquireInfo) {
736 if (acquireInfo != FaceManager.FACE_ACQUIRED_GOOD) {
737 return;
738 }
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700739 if (DEBUG_FACE) Log.d(TAG, "Face acquired");
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200740 for (int i = 0; i < mCallbacks.size(); i++) {
741 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
742 if (cb != null) {
743 cb.onBiometricAcquired(BiometricSourceType.FACE);
744 }
745 }
746 }
747
748 private void handleFaceAuthenticated(int authUserId) {
749 Trace.beginSection("KeyGuardUpdateMonitor#handlerFaceAuthenticated");
750 try {
751 final int userId;
752 try {
753 userId = ActivityManager.getService().getCurrentUser().id;
754 } catch (RemoteException e) {
755 Log.e(TAG, "Failed to get current user id: ", e);
756 return;
757 }
758 if (userId != authUserId) {
759 Log.d(TAG, "Face authenticated for wrong user: " + authUserId);
760 return;
761 }
762 if (isFaceDisabled(userId)) {
763 Log.d(TAG, "Face authentication disabled by DPM for userId: " + userId);
764 return;
765 }
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700766 if (DEBUG_FACE) Log.d(TAG, "Face auth succeeded for user " + userId);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200767 onFaceAuthenticated(userId);
768 } finally {
769 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
770 }
771 Trace.endSection();
772 }
773
774 private void handleFaceHelp(int msgId, String helpString) {
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700775 if (DEBUG_FACE) Log.d(TAG, "Face help received: " + helpString);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200776 for (int i = 0; i < mCallbacks.size(); i++) {
777 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
778 if (cb != null) {
779 cb.onBiometricHelp(msgId, helpString, BiometricSourceType.FACE);
780 }
781 }
782 }
783
784 private Runnable mRetryFaceAuthentication = new Runnable() {
785 @Override
786 public void run() {
787 Log.w(TAG, "Retrying face after HW unavailable, attempt " +
788 mHardwareFaceUnavailableRetryCount);
789 updateFaceListeningState();
790 }
791 };
792
793 private void handleFaceError(int msgId, String errString) {
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700794 if (DEBUG_FACE) Log.d(TAG, "Face error received: " + errString);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200795 if (msgId == FaceManager.FACE_ERROR_CANCELED
796 && mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
797 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
Kevin Chyn1123ba72018-10-26 10:34:06 -0700798 updateFaceListeningState();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200799 } else {
800 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
801 }
802
803 if (msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE) {
804 if (mHardwareFaceUnavailableRetryCount < HW_UNAVAILABLE_RETRY_MAX) {
805 mHardwareFaceUnavailableRetryCount++;
806 mHandler.removeCallbacks(mRetryFaceAuthentication);
807 mHandler.postDelayed(mRetryFaceAuthentication, HW_UNAVAILABLE_TIMEOUT);
808 }
809 }
810
811 if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
812 mLockPatternUtils.requireStrongAuth(
813 LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
814 getCurrentUser());
815 }
816
Lucas Dupin51996bb2019-05-16 17:56:43 -0700817 // The face timeout message is not very actionable, let's ask the user to
818 // manually retry.
819 if (msgId == FaceManager.FACE_ERROR_TIMEOUT) {
820 errString = mContext.getString(R.string.keyguard_unlock);
821 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200822 for (int i = 0; i < mCallbacks.size(); i++) {
823 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
824 if (cb != null) {
825 cb.onBiometricError(msgId, errString,
826 BiometricSourceType.FACE);
827 }
828 }
829 }
830
831 private void handleFaceLockoutReset() {
832 updateFaceListeningState();
833 }
834
835 private void setFaceRunningState(int faceRunningState) {
836 boolean wasRunning = mFaceRunningState == BIOMETRIC_STATE_RUNNING;
837 boolean isRunning = faceRunningState == BIOMETRIC_STATE_RUNNING;
838 mFaceRunningState = faceRunningState;
Kevin Chynb4514d22019-04-15 13:47:25 -0700839 Log.d(TAG, "faceRunningState: " + mFaceRunningState);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200840 // Clients of KeyguardUpdateMonitor don't care about the internal state or about the
Kevin Chynb4514d22019-04-15 13:47:25 -0700841 // asynchronousness of the cancel cycle. So only notify them if the actually running state
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200842 // has changed.
843 if (wasRunning != isRunning) {
844 notifyFaceRunningStateChanged();
845 }
846 }
847
848 private void notifyFaceRunningStateChanged() {
849 for (int i = 0; i < mCallbacks.size(); i++) {
850 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
851 if (cb != null) {
852 cb.onBiometricRunningStateChanged(isFaceDetectionRunning(),
853 BiometricSourceType.FACE);
854 }
855 }
856 }
857
Adrian Roos4a410172014-08-20 17:41:44 +0200858 private void handleFaceUnlockStateChanged(boolean running, int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200859 checkIsHandlerThread();
Adrian Roos4a410172014-08-20 17:41:44 +0200860 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200861 for (int i = 0; i < mCallbacks.size(); i++) {
862 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
863 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200864 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200865 }
866 }
867 }
868
Adrian Roos4a410172014-08-20 17:41:44 +0200869 public boolean isFaceUnlockRunning(int userId) {
870 return mUserFaceUnlockRunning.get(userId);
871 }
872
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700873 public boolean isFingerprintDetectionRunning() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200874 return mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
875 }
876
877 public boolean isFaceDetectionRunning() {
878 return mFaceRunningState == BIOMETRIC_STATE_RUNNING;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700879 }
880
Jim Miller50e62182014-04-23 17:25:00 -0700881 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100882 // Don't allow trust agent if device is secured with a SIM PIN. This is here
883 // mainly because there's no other way to prompt the user to enter their SIM PIN
884 // once they get past the keyguard screen.
885 final boolean disabledBySimPin = isSimPinSecure();
886 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700887 }
888
Jim Miller06e34502014-07-17 14:46:05 -0700889 private boolean isFingerprintDisabled(int userId) {
890 final DevicePolicyManager dpm =
891 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
892 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
Adrian Roos733b6632015-08-21 14:32:35 -0700893 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0
894 || isSimPinSecure();
Jim Miller06e34502014-07-17 14:46:05 -0700895 }
896
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200897 private boolean isFaceDisabled(int userId) {
898 final DevicePolicyManager dpm =
899 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
900 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
901 & DevicePolicyManager.KEYGUARD_DISABLE_FACE) != 0
902 || isSimPinSecure();
903 }
904
905
Selim Cineke8bae622015-07-15 13:24:06 -0700906 public boolean getUserCanSkipBouncer(int userId) {
Steven Wucfe398d2019-03-21 11:32:15 -0400907 return getUserHasTrust(userId) || getUserUnlockedWithBiometric(userId);
Selim Cineke8bae622015-07-15 13:24:06 -0700908 }
909
Adrian Roos46842d92014-03-27 14:58:03 +0100910 public boolean getUserHasTrust(int userId) {
Selim Cineke8bae622015-07-15 13:24:06 -0700911 return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100912 }
913
Steven Wucfe398d2019-03-21 11:32:15 -0400914 /**
915 * Returns whether the user is unlocked with biometrics.
916 */
917 public boolean getUserUnlockedWithBiometric(int userId) {
918 boolean fingerprintOrFace = mUserFingerprintAuthenticated.get(userId)
919 || mUserFaceAuthenticated.get(userId);
920 return fingerprintOrFace && isUnlockingWithBiometricAllowed();
921 }
922
Adrian Roos7861c662014-07-25 15:37:28 +0200923 public boolean getUserTrustIsManaged(int userId) {
924 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
925 }
926
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200927 public boolean isUnlockingWithBiometricAllowed() {
928 return mStrongAuthTracker.isUnlockingWithBiometricAllowed();
Adrian Roosb5e47222015-08-14 15:53:06 -0700929 }
930
Lucas Dupin16013822018-05-17 18:00:16 -0700931 public boolean isUserInLockdown(int userId) {
932 return mStrongAuthTracker.getStrongAuthForUser(userId)
933 == LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
934 }
935
Jorim Jaggi031f7952016-09-01 16:39:26 -0700936 public boolean needsSlowUnlockTransition() {
937 return mNeedsSlowUnlockTransition;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700938 }
939
Adrian Roosb5e47222015-08-14 15:53:06 -0700940 public StrongAuthTracker getStrongAuthTracker() {
941 return mStrongAuthTracker;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700942 }
943
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700944 private void notifyStrongAuthStateChanged(int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200945 checkIsHandlerThread();
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700946 for (int i = 0; i < mCallbacks.size(); i++) {
947 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
948 if (cb != null) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700949 cb.onStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700950 }
951 }
Selim Cinek1fcafc42015-07-20 14:39:25 -0700952 }
953
Adrian Roos91ba3072017-02-14 16:50:46 +0100954 public boolean isScreenOn() {
955 return mScreenOn;
956 }
957
Lucas Dupinef886542018-01-03 16:03:07 -0800958 private void dispatchErrorMessage(CharSequence message) {
959 for (int i = 0; i < mCallbacks.size(); i++) {
960 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
961 if (cb != null) {
962 cb.onTrustAgentErrorMessage(message);
963 }
964 }
965 }
966
Lucas Dupin3d053532019-01-29 12:35:22 -0800967 @VisibleForTesting
968 void setAssistantVisible(boolean assistantVisible) {
969 mAssistantVisible = assistantVisible;
970 updateBiometricListeningState();
971 }
972
Jim Miller8f09fd22013-03-14 19:04:28 -0700973 static class DisplayClientState {
974 public int clientGeneration;
975 public boolean clearing;
976 public PendingIntent intent;
977 public int playbackState;
978 public long playbackEventTime;
979 }
980
981 private DisplayClientState mDisplayClientState = new DisplayClientState();
982
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800983 @VisibleForTesting
Lucas Dupin7ff82b02018-05-16 12:14:10 -0700984 protected final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
Jim Millerbbf1a742012-07-17 18:30:30 -0700985
Jim Millerd72d5ac2015-09-29 18:55:32 -0700986 @Override
Jim Millerbbf1a742012-07-17 18:30:30 -0700987 public void onReceive(Context context, Intent intent) {
988 final String action = intent.getAction();
989 if (DEBUG) Log.d(TAG, "received broadcast " + action);
990
991 if (Intent.ACTION_TIME_TICK.equals(action)
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500992 || Intent.ACTION_TIME_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700993 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500994 } else if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
995 final Message msg = mHandler.obtainMessage(
996 MSG_TIMEZONE_UPDATE, intent.getStringExtra("time-zone"));
997 mHandler.sendMessage(msg);
Jim Millerbbf1a742012-07-17 18:30:30 -0700998 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
999 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
1000 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
1001 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
1002 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
Adrian Roos0c859ae2015-11-23 16:47:50 -08001003
1004 final int maxChargingMicroAmp = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
1005 int maxChargingMicroVolt = intent.getIntExtra(EXTRA_MAX_CHARGING_VOLTAGE, -1);
1006 final int maxChargingMicroWatt;
1007
1008 if (maxChargingMicroVolt <= 0) {
1009 maxChargingMicroVolt = DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT;
1010 }
1011 if (maxChargingMicroAmp > 0) {
1012 // Calculating muW = muA * muV / (10^6 mu^2 / mu); splitting up the divisor
1013 // to maintain precision equally on both factors.
1014 maxChargingMicroWatt = (maxChargingMicroAmp / 1000)
1015 * (maxChargingMicroVolt / 1000);
1016 } else {
1017 maxChargingMicroWatt = -1;
1018 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001019 final Message msg = mHandler.obtainMessage(
Adrian Roos7b043112015-07-10 13:00:33 -07001020 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
Adrian Roos0c859ae2015-11-23 16:47:50 -08001021 maxChargingMicroWatt));
Jim Millerbbf1a742012-07-17 18:30:30 -07001022 mHandler.sendMessage(msg);
1023 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Bill Linef81cbd2018-07-05 17:48:49 +08001024 SimData args = SimData.fromIntent(intent);
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001025 // ACTION_SIM_STATE_CHANGED is rebroadcast after unlocking the device to
1026 // keep compatibility with apps that aren't direct boot aware.
1027 // SysUI should just ignore this broadcast because it was already received
1028 // and processed previously.
1029 if (intent.getBooleanExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
Bill Linef81cbd2018-07-05 17:48:49 +08001030 // Guarantee mTelephonyCapable state after SysUI crash and restart
1031 if (args.simState == State.ABSENT) {
1032 mHandler.obtainMessage(MSG_TELEPHONY_CAPABLE, true).sendToTarget();
1033 }
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001034 return;
1035 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001036 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -08001037 Log.v(TAG, "action " + action
1038 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
1039 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -07001040 }
Jim Miller52a61332014-11-12 19:29:51 -08001041 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
1042 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -07001043 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
1044 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
1045 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
1046 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
1047 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
1048 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Jason Monk052082c2015-06-11 11:35:23 -04001049 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
1050 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001051 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -07001052 dispatchBootCompleted();
Etan Cohen47051d82015-07-06 16:19:04 -07001053 } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
1054 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
1055 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
1056 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
1057 if (DEBUG) {
1058 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
1059 + subId);
1060 }
Bonian Chena7e9e8c2019-06-02 23:59:31 +00001061 mHandler.sendMessage(
1062 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
Alex Chauff7653d2018-02-01 17:18:08 +00001063 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
1064 action)) {
1065 mHandler.sendEmptyMessage(MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001066 }
1067 }
1068 };
Jim Miller2de5ee82012-06-14 22:22:50 -07001069
Lucas Dupin3d053532019-01-29 12:35:22 -08001070 @VisibleForTesting
1071 protected final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001072
Jim Millerd72d5ac2015-09-29 18:55:32 -07001073 @Override
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001074 public void onReceive(Context context, Intent intent) {
1075 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +02001076 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
1077 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
1078 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001079 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
1080 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +02001081 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001082 Trace.beginSection("KeyguardUpdateMonitor.mBroadcastAllReceiver#onReceive ACTION_FACE_UNLOCK_STARTED");
Adrian Roos48c796c2014-09-01 14:59:23 +02001083 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
1084 getSendingUserId()));
Nick Desaulniers1d396752016-07-25 15:05:33 -07001085 Trace.endSection();
Adrian Roos48c796c2014-09-01 14:59:23 +02001086 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
1087 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
1088 getSendingUserId()));
1089 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
1090 .equals(action)) {
1091 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001092 } else if (ACTION_USER_UNLOCKED.equals(action)) {
1093 mHandler.sendEmptyMessage(MSG_USER_UNLOCKED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001094 }
1095 }
1096 };
Jim Miller9f0753f2015-03-23 23:59:22 -07001097
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001098 private final FingerprintManager.LockoutResetCallback mFingerprintLockoutResetCallback
Jorim Jaggi3a464782015-08-28 16:59:13 -07001099 = new FingerprintManager.LockoutResetCallback() {
1100 @Override
1101 public void onLockoutReset() {
1102 handleFingerprintLockoutReset();
1103 }
1104 };
1105
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001106 private final FaceManager.LockoutResetCallback mFaceLockoutResetCallback
1107 = new FaceManager.LockoutResetCallback() {
1108 @Override
1109 public void onLockoutReset() {
1110 handleFaceLockoutReset();
1111 }
1112 };
1113
1114 private FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback
Jim Miller9f0753f2015-03-23 23:59:22 -07001115 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -07001116
1117 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -07001118 public void onAuthenticationFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001119 handleFingerprintAuthFailed();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001120 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001121
1122 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -07001123 public void onAuthenticationSucceeded(AuthenticationResult result) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001124 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
Jim Miller837fa7e2016-08-08 20:16:22 -07001125 handleFingerprintAuthenticated(result.getUserId());
Nick Desaulniers1d396752016-07-25 15:05:33 -07001126 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -07001127 }
1128
1129 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -07001130 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001131 handleFingerprintHelp(helpMsgId, helpString.toString());
Jim Miller9f0753f2015-03-23 23:59:22 -07001132 }
1133
1134 @Override
1135 public void onAuthenticationError(int errMsgId, CharSequence errString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001136 handleFingerprintError(errMsgId, errString.toString());
1137 }
1138
1139 @Override
1140 public void onAuthenticationAcquired(int acquireInfo) {
1141 handleFingerprintAcquired(acquireInfo);
Jim Millerf41fc962014-06-18 16:33:51 -07001142 }
1143 };
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001144
Lucas Dupin3d053532019-01-29 12:35:22 -08001145 @VisibleForTesting
1146 FaceManager.AuthenticationCallback mFaceAuthenticationCallback
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001147 = new FaceManager.AuthenticationCallback() {
1148
1149 @Override
1150 public void onAuthenticationFailed() {
1151 handleFaceAuthFailed();
1152 }
1153
1154 @Override
1155 public void onAuthenticationSucceeded(FaceManager.AuthenticationResult result) {
1156 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
1157 handleFaceAuthenticated(result.getUserId());
1158 Trace.endSection();
1159 }
1160
1161 @Override
1162 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
1163 handleFaceHelp(helpMsgId, helpString.toString());
1164 }
1165
1166 @Override
1167 public void onAuthenticationError(int errMsgId, CharSequence errString) {
1168 handleFaceError(errMsgId, errString.toString());
1169 }
1170
1171 @Override
1172 public void onAuthenticationAcquired(int acquireInfo) {
1173 handleFaceAcquired(acquireInfo);
1174 }
1175 };
1176
Jim Miller9f0753f2015-03-23 23:59:22 -07001177 private CancellationSignal mFingerprintCancelSignal;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001178 private CancellationSignal mFaceCancelSignal;
Jim Miller9f0753f2015-03-23 23:59:22 -07001179 private FingerprintManager mFpm;
Kevin Chynb7b54a62018-09-28 18:48:12 -07001180 private FaceManager mFaceManager;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001181
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001182 /**
Jim Miller47088bb2009-11-24 00:40:16 -08001183 * When we receive a
1184 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -07001185 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001186 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -08001187 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001188 */
Jim Miller52a61332014-11-12 19:29:51 -08001189 private static class SimData {
1190 public State simState;
1191 public int slotId;
1192 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001193
Jim Miller52a61332014-11-12 19:29:51 -08001194 SimData(State state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -08001195 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -08001196 slotId = slot;
1197 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -08001198 }
1199
Jim Miller52a61332014-11-12 19:29:51 -08001200 static SimData fromIntent(Intent intent) {
1201 State state;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001202 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
1203 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
1204 }
Wink Savillea639b312012-07-10 12:37:54 -07001205 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
Jayachandran Cbd481352019-05-21 16:02:23 -07001206 int slotId = intent.getIntExtra(PhoneConstants.PHONE_KEY, 0);
Jim Miller52a61332014-11-12 19:29:51 -08001207 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
Wink Savilled09c4ca2014-11-22 10:08:16 -08001208 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea639b312012-07-10 12:37:54 -07001209 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -07001210 final String absentReason = intent
Wink Savillea639b312012-07-10 12:37:54 -07001211 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -07001212
Wink Savillea639b312012-07-10 12:37:54 -07001213 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -07001214 absentReason)) {
Wink Savillea639b312012-07-10 12:37:54 -07001215 state = IccCardConstants.State.PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -07001216 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001217 state = IccCardConstants.State.ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -07001218 }
Wink Savillea639b312012-07-10 12:37:54 -07001219 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
1220 state = IccCardConstants.State.READY;
1221 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001222 final String lockedReason = intent
Wink Savillea639b312012-07-10 12:37:54 -07001223 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
1224 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
1225 state = IccCardConstants.State.PIN_REQUIRED;
1226 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
1227 state = IccCardConstants.State.PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001228 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001229 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001230 }
Wink Savillea639b312012-07-10 12:37:54 -07001231 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
1232 state = IccCardConstants.State.NETWORK_LOCKED;
Wileen Chiu6b8b22e2014-10-29 22:48:21 +05301233 } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
1234 state = IccCardConstants.State.CARD_IO_ERROR;
Jim Miller109f1fd2012-09-19 20:44:16 -07001235 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
1236 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
1237 // This is required because telephony doesn't return to "READY" after
1238 // these state transitions. See bug 7197471.
1239 state = IccCardConstants.State.READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001240 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001241 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001242 }
Jim Miller52a61332014-11-12 19:29:51 -08001243 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001244 }
1245
Jim Millerd72d5ac2015-09-29 18:55:32 -07001246 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001247 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -08001248 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001249 }
1250 }
1251
Adrian Roos12c1ef52014-06-04 13:54:08 +02001252 public static class BatteryStatus {
Adrian Roos7b043112015-07-10 13:00:33 -07001253 public static final int CHARGING_UNKNOWN = -1;
1254 public static final int CHARGING_SLOWLY = 0;
1255 public static final int CHARGING_REGULAR = 1;
1256 public static final int CHARGING_FAST = 2;
1257
Jim Miller16464b82011-10-20 21:10:13 -07001258 public final int status;
1259 public final int level;
1260 public final int plugged;
1261 public final int health;
Adrian Roos0c859ae2015-11-23 16:47:50 -08001262 public final int maxChargingWattage;
1263 public BatteryStatus(int status, int level, int plugged, int health,
1264 int maxChargingWattage) {
Jim Miller16464b82011-10-20 21:10:13 -07001265 this.status = status;
1266 this.level = level;
1267 this.plugged = plugged;
1268 this.health = health;
Adrian Roos0c859ae2015-11-23 16:47:50 -08001269 this.maxChargingWattage = maxChargingWattage;
Jim Miller16464b82011-10-20 21:10:13 -07001270 }
1271
Jim Millerbbf1a742012-07-17 18:30:30 -07001272 /**
Brian Muramatsua92a01b2012-09-05 21:54:39 -07001273 * Determine whether the device is plugged in (USB, power, or wireless).
Jim Millerbbf1a742012-07-17 18:30:30 -07001274 * @return true if the device is plugged in.
1275 */
Adrian Roosad3bc7f2014-10-30 18:29:38 +01001276 public boolean isPluggedIn() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001277 return plugged == BatteryManager.BATTERY_PLUGGED_AC
Brian Muramatsua92a01b2012-09-05 21:54:39 -07001278 || plugged == BatteryManager.BATTERY_PLUGGED_USB
1279 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Jim Millerbbf1a742012-07-17 18:30:30 -07001280 }
1281
1282 /**
Beverly2034c832018-03-19 11:18:51 -04001283 * Determine whether the device is plugged in (USB, power).
1284 * @return true if the device is plugged in wired (as opposed to wireless)
1285 */
1286 public boolean isPluggedInWired() {
1287 return plugged == BatteryManager.BATTERY_PLUGGED_AC
1288 || plugged == BatteryManager.BATTERY_PLUGGED_USB;
1289 }
1290
1291 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001292 * Whether or not the device is charged. Note that some devices never return 100% for
1293 * battery level, so this allows either battery level or status to determine if the
1294 * battery is charged.
1295 * @return true if the device is charged
1296 */
1297 public boolean isCharged() {
1298 return status == BATTERY_STATUS_FULL || level >= 100;
1299 }
1300
1301 /**
1302 * Whether battery is low and needs to be charged.
1303 * @return true if battery is low
1304 */
1305 public boolean isBatteryLow() {
1306 return level < LOW_BATTERY_THRESHOLD;
1307 }
1308
Adrian Roos7b043112015-07-10 13:00:33 -07001309 public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
Adrian Roos0c859ae2015-11-23 16:47:50 -08001310 return maxChargingWattage <= 0 ? CHARGING_UNKNOWN :
1311 maxChargingWattage < slowThreshold ? CHARGING_SLOWLY :
1312 maxChargingWattage > fastThreshold ? CHARGING_FAST :
Adrian Roos7b043112015-07-10 13:00:33 -07001313 CHARGING_REGULAR;
1314 }
Lucas Dupin3fcdd472018-01-19 19:06:45 -08001315
1316 @Override
1317 public String toString() {
1318 return "BatteryStatus{status=" + status + ",level=" + level + ",plugged=" + plugged
1319 + ",health=" + health + ",maxChargingWattage=" + maxChargingWattage + "}";
1320 }
Jim Miller16464b82011-10-20 21:10:13 -07001321 }
1322
Lucas Dupin3d053532019-01-29 12:35:22 -08001323 public static class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
1324 private final Consumer<Integer> mStrongAuthRequiredChangedCallback;
1325
1326 public StrongAuthTracker(Context context,
1327 Consumer<Integer> strongAuthRequiredChangedCallback) {
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001328 super(context);
Lucas Dupin3d053532019-01-29 12:35:22 -08001329 mStrongAuthRequiredChangedCallback = strongAuthRequiredChangedCallback;
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001330 }
Adrian Roosb5e47222015-08-14 15:53:06 -07001331
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001332 public boolean isUnlockingWithBiometricAllowed() {
Adrian Roosb5e47222015-08-14 15:53:06 -07001333 int userId = getCurrentUser();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001334 return isBiometricAllowedForUser(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -07001335 }
1336
1337 public boolean hasUserAuthenticatedSinceBoot() {
1338 int userId = getCurrentUser();
1339 return (getStrongAuthForUser(userId)
1340 & STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
1341 }
1342
1343 @Override
1344 public void onStrongAuthRequiredChanged(int userId) {
Lucas Dupin3d053532019-01-29 12:35:22 -08001345 mStrongAuthRequiredChangedCallback.accept(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -07001346 }
1347 }
1348
Jim Millerdcb3d842012-08-23 19:18:12 -07001349 public static KeyguardUpdateMonitor getInstance(Context context) {
1350 if (sInstance == null) {
1351 sInstance = new KeyguardUpdateMonitor(context);
1352 }
1353 return sInstance;
1354 }
1355
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001356 protected void handleStartedWakingUp() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001357 Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001358 updateBiometricListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001359 final int count = mCallbacks.size();
1360 for (int i = 0; i < count; i++) {
1361 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1362 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001363 cb.onStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -07001364 }
1365 }
Nick Desaulniers1d396752016-07-25 15:05:33 -07001366 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -07001367 }
1368
Jorim Jaggi95e40382015-09-16 15:53:42 -07001369 protected void handleStartedGoingToSleep(int arg1) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001370 clearBiometricRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -07001371 final int count = mCallbacks.size();
1372 for (int i = 0; i < count; i++) {
1373 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1374 if (cb != null) {
Jorim Jaggi95e40382015-09-16 15:53:42 -07001375 cb.onStartedGoingToSleep(arg1);
1376 }
1377 }
1378 mGoingToSleep = true;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001379 updateBiometricListeningState();
Jorim Jaggi95e40382015-09-16 15:53:42 -07001380 }
1381
1382 protected void handleFinishedGoingToSleep(int arg1) {
1383 mGoingToSleep = false;
1384 final int count = mCallbacks.size();
1385 for (int i = 0; i < count; i++) {
1386 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1387 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001388 cb.onFinishedGoingToSleep(arg1);
Jim Miller20daffd2013-10-07 14:59:53 -07001389 }
1390 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001391 updateBiometricListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001392 }
1393
Jorim Jaggif1518da2015-07-30 11:56:36 -07001394 private void handleScreenTurnedOn() {
1395 final int count = mCallbacks.size();
1396 for (int i = 0; i < count; i++) {
1397 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1398 if (cb != null) {
1399 cb.onScreenTurnedOn();
1400 }
1401 }
1402 }
1403
1404 private void handleScreenTurnedOff() {
Lucas Dupinca88e5f2019-05-14 16:11:08 -07001405 mLockIconPressed = false;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001406 mHardwareFingerprintUnavailableRetryCount = 0;
1407 mHardwareFaceUnavailableRetryCount = 0;
Jorim Jaggif1518da2015-07-30 11:56:36 -07001408 final int count = mCallbacks.size();
1409 for (int i = 0; i < count; i++) {
1410 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1411 if (cb != null) {
1412 cb.onScreenTurnedOff();
1413 }
1414 }
1415 }
1416
Selim Cinek99415392016-09-09 14:58:41 -07001417 private void handleDreamingStateChanged(int dreamStart) {
1418 final int count = mCallbacks.size();
Kevin Chyn36778ff2017-09-07 19:55:38 -07001419 mIsDreaming = dreamStart == 1;
Selim Cinek99415392016-09-09 14:58:41 -07001420 for (int i = 0; i < count; i++) {
1421 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1422 if (cb != null) {
Kevin Chyn36778ff2017-09-07 19:55:38 -07001423 cb.onDreamingStateChanged(mIsDreaming);
Selim Cinek99415392016-09-09 14:58:41 -07001424 }
1425 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001426 updateBiometricListeningState();
Selim Cinek99415392016-09-09 14:58:41 -07001427 }
1428
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001429 private void handleUserInfoChanged(int userId) {
1430 for (int i = 0; i < mCallbacks.size(); i++) {
1431 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1432 if (cb != null) {
1433 cb.onUserInfoChanged(userId);
1434 }
1435 }
1436 }
1437
Jorim Jaggidadafd42016-09-30 07:20:25 -07001438 private void handleUserUnlocked() {
1439 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1440 for (int i = 0; i < mCallbacks.size(); i++) {
1441 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1442 if (cb != null) {
1443 cb.onUserUnlocked();
1444 }
1445 }
1446 }
1447
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001448 @VisibleForTesting
1449 protected KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001450 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -08001451 mSubscriptionManager = SubscriptionManager.from(context);
Michael Jurkafff56142012-11-28 16:51:00 -08001452 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Lucas Dupin3d053532019-01-29 12:35:22 -08001453 mStrongAuthTracker = new StrongAuthTracker(context, this::notifyStrongAuthStateChanged);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001454
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001455 // Since device can't be un-provisioned, we only need to register a content observer
1456 // to update mDeviceProvisioned when we are...
1457 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001458 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001459 }
Jim Miller47088bb2009-11-24 00:40:16 -08001460
Jim Millerbbf1a742012-07-17 18:30:30 -07001461 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Adrian Roos7b043112015-07-10 13:00:33 -07001462 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001463
Jim Millerbbf1a742012-07-17 18:30:30 -07001464 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001465 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001466 filter.addAction(Intent.ACTION_TIME_TICK);
1467 filter.addAction(Intent.ACTION_TIME_CHANGED);
1468 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
1469 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Jason Monk052082c2015-06-11 11:35:23 -04001470 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001471 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Etan Cohen47051d82015-07-06 16:19:04 -07001472 filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -08001473 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -08001474 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Alex Chauff7653d2018-02-01 17:18:08 +00001475 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jason Monk7bb59302018-05-10 19:38:18 -07001476 context.registerReceiver(mBroadcastReceiver, filter, null, mHandler);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001477
Adam Cohenc276e822012-11-08 13:01:08 -08001478 final IntentFilter bootCompleteFilter = new IntentFilter();
1479 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1480 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
Jason Monk7bb59302018-05-10 19:38:18 -07001481 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter, null, mHandler);
Adam Cohenc276e822012-11-08 13:01:08 -08001482
Adrian Roos48c796c2014-09-01 14:59:23 +02001483 final IntentFilter allUserFilter = new IntentFilter();
1484 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
1485 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
1486 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
1487 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
1488 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001489 allUserFilter.addAction(ACTION_USER_UNLOCKED);
Adrian Roos48c796c2014-09-01 14:59:23 +02001490 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Jason Monk7bb59302018-05-10 19:38:18 -07001491 null, mHandler);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001492
Wink Saville071743f2015-01-12 17:11:04 -08001493 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001494 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001495 ActivityManager.getService().registerUserSwitchObserver(
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001496 new UserSwitchObserver() {
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001497 @Override
1498 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001499 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001500 newUserId, 0, reply));
1501 }
1502 @Override
1503 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001504 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +02001505 newUserId, 0));
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001506 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001507 }, TAG);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001508 } catch (RemoteException e) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001509 e.rethrowAsRuntimeException();
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001510 }
Adrian Roos46842d92014-03-27 14:58:03 +01001511
Jorim Jaggi237b0612015-05-01 14:28:49 -07001512 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
1513 mTrustManager.registerTrustListener(this);
Michal Karpinskic52f8672016-11-18 11:32:45 +00001514 mLockPatternUtils = new LockPatternUtils(context);
1515 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Jim Millerf41fc962014-06-18 16:33:51 -07001516
Kevin Chyn36778ff2017-09-07 19:55:38 -07001517 mDreamManager = IDreamManager.Stub.asInterface(
1518 ServiceManager.getService(DreamService.DREAM_SERVICE));
1519
Jorim Jaggi3f124262016-11-22 13:45:17 +01001520 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
1521 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
1522 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001523 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
Kevin Chynb7b54a62018-09-28 18:48:12 -07001524 mFaceManager = (FaceManager) context.getSystemService(Context.FACE_SERVICE);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001525 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07001526
1527 if (mFpm != null || mFaceManager != null) {
1528 mBiometricManager = context.getSystemService(BiometricManager.class);
1529 mBiometricManager.registerEnabledOnKeyguardCallback(mBiometricEnabledCallback);
1530 }
1531
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001532 updateBiometricListeningState();
Jorim Jaggi3a464782015-08-28 16:59:13 -07001533 if (mFpm != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001534 mFpm.addLockoutResetCallback(mFingerprintLockoutResetCallback);
1535 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07001536 if (mFaceManager != null) {
1537 mFaceManager.addLockoutResetCallback(mFaceLockoutResetCallback);
Jorim Jaggi3a464782015-08-28 16:59:13 -07001538 }
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001539
Winson Chung2cf6ad82017-11-09 17:36:59 -08001540 ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001541 mUserManager = context.getSystemService(UserManager.class);
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001542 mIsPrimaryUser = mUserManager.isPrimaryUser();
Alex Chauff7653d2018-02-01 17:18:08 +00001543 mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
1544 mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
Bill Linef81cbd2018-07-05 17:48:49 +08001545 updateAirplaneModeState();
1546 }
1547
1548 private void updateAirplaneModeState() {
1549 // ACTION_AIRPLANE_MODE_CHANGED do not broadcast if device set AirplaneMode ON and boot
1550 if (!WirelessUtils.isAirplaneModeOn(mContext)
1551 || mHandler.hasMessages(MSG_AIRPLANE_MODE_CHANGED)) {
1552 return;
1553 }
1554 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Jorim Jaggiea657062015-04-28 13:45:11 -07001555 }
1556
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001557 private void updateBiometricListeningState() {
1558 updateFingerprintListeningState();
1559 updateFaceListeningState();
1560 }
1561
Jorim Jaggiea657062015-04-28 13:45:11 -07001562 private void updateFingerprintListeningState() {
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001563 // If this message exists, we should not authenticate again until this message is
1564 // consumed by the handler
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001565 if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001566 return;
1567 }
Kevin Chyn0c45b072017-04-24 16:27:11 -07001568 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
Jorim Jaggiea657062015-04-28 13:45:11 -07001569 boolean shouldListenForFingerprint = shouldListenForFingerprint();
Adrian Roos2aaf9442018-11-20 16:57:33 +01001570 boolean runningOrRestarting = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING
1571 || mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING;
1572 if (runningOrRestarting && !shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001573 stopListeningForFingerprint();
Adrian Roos2aaf9442018-11-20 16:57:33 +01001574 } else if (!runningOrRestarting && shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001575 startListeningForFingerprint();
1576 }
1577 }
1578
Lucas Dupin3d053532019-01-29 12:35:22 -08001579 /**
Lucas Dupine0516d52019-02-05 17:54:06 -05001580 * Called whenever passive authentication is requested or aborted by a sensor.
1581 * @param active If the interrupt started or ended.
Lucas Dupin3d053532019-01-29 12:35:22 -08001582 */
Lucas Dupine0516d52019-02-05 17:54:06 -05001583 public void onAuthInterruptDetected(boolean active) {
1584 if (DEBUG) Log.d(TAG, "onAuthInterruptDetected(" + active + ")");
1585 if (mAuthInterruptActive == active) {
1586 return;
1587 }
1588 mAuthInterruptActive = active;
Lucas Dupin3d053532019-01-29 12:35:22 -08001589 updateFaceListeningState();
1590 }
1591
Lucas Dupin8f3faac2019-03-12 15:28:49 -07001592 /**
1593 * Requests face authentication if we're on a state where it's allowed.
1594 * This will re-trigger auth in case it fails.
1595 */
1596 public void requestFaceAuth() {
1597 if (DEBUG) Log.d(TAG, "requestFaceAuth()");
1598 updateFaceListeningState();
1599 }
1600
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001601 private void updateFaceListeningState() {
1602 // If this message exists, we should not authenticate again until this message is
1603 // consumed by the handler
1604 if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
1605 return;
1606 }
1607 mHandler.removeCallbacks(mRetryFaceAuthentication);
1608 boolean shouldListenForFace = shouldListenForFace();
1609 if (mFaceRunningState == BIOMETRIC_STATE_RUNNING && !shouldListenForFace) {
1610 stopListeningForFace();
1611 } else if (mFaceRunningState != BIOMETRIC_STATE_RUNNING
1612 && shouldListenForFace) {
1613 startListeningForFace();
1614 }
1615 }
1616
Kevin Chyn129f60f2017-08-11 17:24:42 -07001617 private boolean shouldListenForFingerprintAssistant() {
1618 return mAssistantVisible && mKeyguardOccluded
1619 && !mUserFingerprintAuthenticated.get(getCurrentUser(), false)
1620 && !mUserHasTrust.get(getCurrentUser(), false);
1621 }
1622
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001623 private boolean shouldListenForFaceAssistant() {
1624 return mAssistantVisible && mKeyguardOccluded
1625 && !mUserFaceAuthenticated.get(getCurrentUser(), false)
1626 && !mUserHasTrust.get(getCurrentUser(), false);
1627 }
1628
Jorim Jaggiea657062015-04-28 13:45:11 -07001629 private boolean shouldListenForFingerprint() {
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001630 // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
1631 // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
1632 final boolean shouldListen = (mKeyguardIsVisible || !mDeviceInteractive ||
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001633 (mBouncer && !mKeyguardGoingAway) || mGoingToSleep ||
Kevin Chyn36778ff2017-09-07 19:55:38 -07001634 shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming))
Lucas Dupinc12fad32019-05-14 20:59:17 +00001635 && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser())
Kevin Chyn225eea72019-03-06 16:42:00 -08001636 && (!mKeyguardGoingAway || !mDeviceInteractive) && mIsPrimaryUser;
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001637 return shouldListen;
Jim Miller9f0753f2015-03-23 23:59:22 -07001638 }
1639
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001640 private boolean shouldListenForFace() {
Lucas Dupin3d053532019-01-29 12:35:22 -08001641 final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep;
1642 final int user = getCurrentUser();
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001643 // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
1644 // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
Lucas Dupine0516d52019-02-05 17:54:06 -05001645 return (mBouncer || mAuthInterruptActive || awakeKeyguard || shouldListenForFaceAssistant())
Lucas Dupinc12fad32019-05-14 20:59:17 +00001646 && !mSwitchingUser && !getUserCanSkipBouncer(user) && !isFaceDisabled(user)
Lucas Dupinca88e5f2019-05-14 16:11:08 -07001647 && !mKeyguardGoingAway && mFaceSettingEnabledForUser && !mLockIconPressed
Kevin Chyn0d9eccf2019-03-01 16:23:49 -08001648 && mUserManager.isUserUnlocked(user) && mIsPrimaryUser;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001649 }
1650
Lucas Dupinca88e5f2019-05-14 16:11:08 -07001651 /**
1652 * Whenever the lock icon is long pressed, disabling trust agents.
1653 * This means that we cannot auth passively (face) until the user presses power.
1654 */
1655 public void onLockIconPressed() {
1656 mLockIconPressed = true;
1657 mUserFaceAuthenticated.put(getCurrentUser(), false);
1658 updateFaceListeningState();
1659 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001660
Jim Millerce7eb6d2015-04-03 19:29:13 -07001661 private void startListeningForFingerprint() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001662 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING) {
1663 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001664 return;
1665 }
Adrian Roos2aaf9442018-11-20 16:57:33 +01001666 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1667 // Waiting for restart via handleFingerprintError().
1668 return;
1669 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001670 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Lucas Dupin8f3faac2019-03-12 15:28:49 -07001671 int userId = getCurrentUser();
Jorim Jaggi71448a72015-08-18 19:49:04 -07001672 if (isUnlockWithFingerprintPossible(userId)) {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001673 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001674 mFingerprintCancelSignal.cancel();
1675 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001676 mFingerprintCancelSignal = new CancellationSignal();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001677 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mFingerprintAuthenticationCallback,
1678 null, userId);
1679 setFingerprintRunningState(BIOMETRIC_STATE_RUNNING);
1680 }
1681 }
1682
1683 private void startListeningForFace() {
1684 if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING) {
1685 setFaceRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);
1686 return;
1687 }
1688 if (DEBUG) Log.v(TAG, "startListeningForFace()");
Lucas Dupin8f3faac2019-03-12 15:28:49 -07001689 int userId = getCurrentUser();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001690 if (isUnlockWithFacePossible(userId)) {
1691 if (mFaceCancelSignal != null) {
1692 mFaceCancelSignal.cancel();
1693 }
1694 mFaceCancelSignal = new CancellationSignal();
Kevin Chynb7b54a62018-09-28 18:48:12 -07001695 mFaceManager.authenticate(null, mFaceCancelSignal, 0,
Kevin Chyn8d2694a2019-04-11 18:30:40 -07001696 mFaceAuthenticationCallback, null, userId);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001697 setFaceRunningState(BIOMETRIC_STATE_RUNNING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001698 }
1699 }
1700
Lucas Dupin8d48fc42019-04-25 14:34:12 -07001701 /**
1702 * If biometrics hardware is available, not disabled, and user has enrolled templates.
1703 * This does NOT check if the device is encrypted or in lockdown.
1704 *
1705 * @param userId User that's trying to unlock.
1706 * @return {@code true} if possible.
1707 */
1708 public boolean isUnlockingWithBiometricsPossible(int userId) {
1709 return isUnlockWithFacePossible(userId) || isUnlockWithFingerprintPossible(userId);
1710 }
1711
1712 private boolean isUnlockWithFingerprintPossible(int userId) {
Selim Cinek3122fa82015-06-18 01:38:59 -07001713 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
1714 && mFpm.getEnrolledFingerprints(userId).size() > 0;
1715 }
1716
Lucas Dupin7156bc72019-05-03 19:37:39 -07001717 /**
1718 * If face hardware is available and user has enrolled. Not considering encryption or
1719 * lockdown state.
1720 */
1721 public boolean isUnlockWithFacePossible(int userId) {
Kevin Chynb7b54a62018-09-28 18:48:12 -07001722 return mFaceManager != null && mFaceManager.isHardwareDetected()
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001723 && !isFaceDisabled(userId)
Kevin Chynb7b54a62018-09-28 18:48:12 -07001724 && mFaceManager.hasEnrolledTemplates(userId);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001725 }
1726
Jorim Jaggiea657062015-04-28 13:45:11 -07001727 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001728 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001729 if (mFingerprintRunningState == BIOMETRIC_STATE_RUNNING) {
Kevin Chyn2fefd462017-04-28 12:18:19 -07001730 if (mFingerprintCancelSignal != null) {
1731 mFingerprintCancelSignal.cancel();
1732 mFingerprintCancelSignal = null;
1733 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001734 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001735 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001736 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1737 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING);
1738 }
1739 }
1740
1741 private void stopListeningForFace() {
1742 if (DEBUG) Log.v(TAG, "stopListeningForFace()");
1743 if (mFaceRunningState == BIOMETRIC_STATE_RUNNING) {
1744 if (mFaceCancelSignal != null) {
1745 mFaceCancelSignal.cancel();
1746 mFaceCancelSignal = null;
1747 }
1748 setFaceRunningState(BIOMETRIC_STATE_CANCELLING);
1749 }
1750 if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1751 setFaceRunningState(BIOMETRIC_STATE_CANCELLING);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001752 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001753 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001754
Michael Jurkafff56142012-11-28 16:51:00 -08001755 private boolean isDeviceProvisionedInSettingsDb() {
1756 return Settings.Global.getInt(mContext.getContentResolver(),
1757 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1758 }
1759
Jim Millerbbf1a742012-07-17 18:30:30 -07001760 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -08001761 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001762 @Override
1763 public void onChange(boolean selfChange) {
1764 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -08001765 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001766 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001767 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001768 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001769 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001770 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001771 };
1772
1773 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -07001774 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -08001775 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -07001776
1777 // prevent a race condition between where we check the flag and where we register the
1778 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -08001779 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001780 if (provisioned != mDeviceProvisioned) {
1781 mDeviceProvisioned = provisioned;
1782 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001783 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001784 }
1785 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001786 }
1787
Jim Millerbbf1a742012-07-17 18:30:30 -07001788 /**
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001789 * Update the state whether Keyguard currently has a lockscreen wallpaper.
1790 *
1791 * @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper.
1792 */
1793 public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001794 checkIsHandlerThread();
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001795 if (hasLockscreenWallpaper != mHasLockscreenWallpaper) {
1796 mHasLockscreenWallpaper = hasLockscreenWallpaper;
1797 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1798 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1799 if (cb != null) {
1800 cb.onHasLockscreenWallpaperChanged(hasLockscreenWallpaper);
1801 }
1802 }
1803 }
1804 }
1805
1806 /**
1807 * @return Whether Keyguard has a lockscreen wallpaper.
1808 */
1809 public boolean hasLockscreenWallpaper() {
1810 return mHasLockscreenWallpaper;
1811 }
1812
1813 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001814 * Handle {@link #MSG_DPM_STATE_CHANGED}
1815 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001816 private void handleDevicePolicyManagerStateChanged() {
Adrian Roos733b6632015-08-21 14:32:35 -07001817 updateFingerprintListeningState();
Jim Millerdcb3d842012-08-23 19:18:12 -07001818 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1819 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1820 if (cb != null) {
1821 cb.onDevicePolicyManagerStateChanged();
1822 }
Jim Millerb0304762012-03-13 20:01:25 -07001823 }
1824 }
1825
Jim Millerbbf1a742012-07-17 18:30:30 -07001826 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001827 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -07001828 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001829 private void handleUserSwitching(int userId, IRemoteCallback reply) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001830 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001831 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1832 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001833 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -07001834 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001835 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001836 try {
1837 reply.sendResult(null);
1838 } catch (RemoteException e) {
1839 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001840 }
1841
Jim Millerbbf1a742012-07-17 18:30:30 -07001842 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001843 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
1844 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001845 private void handleUserSwitchComplete(int userId) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001846 for (int i = 0; i < mCallbacks.size(); i++) {
1847 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1848 if (cb != null) {
1849 cb.onUserSwitchComplete(userId);
1850 }
1851 }
1852 }
1853
1854 /**
Jim Miller90873d52013-09-26 18:11:38 -07001855 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
1856 * keyguard crashes sometime after boot, then it will never receive this
1857 * broadcast and hence not handle the event. This method is ultimately called by
1858 * PhoneWindowManager in this case.
1859 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001860 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001861 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -07001862 }
1863
1864 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001865 * Handle {@link #MSG_BOOT_COMPLETED}
1866 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001867 private void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001868 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001869 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001870 for (int i = 0; i < mCallbacks.size(); i++) {
1871 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1872 if (cb != null) {
1873 cb.onBootCompleted();
1874 }
1875 }
1876 }
1877
1878 /**
Jim Miller5ecd8112013-01-09 18:50:26 -08001879 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001880 * destroyed.
1881 */
1882 public boolean hasBootCompleted() {
1883 return mBootCompleted;
1884 }
1885
1886 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001887 * Handle {@link #MSG_DEVICE_PROVISIONED}
1888 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001889 private void handleDeviceProvisioned() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001890 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001891 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1892 if (cb != null) {
1893 cb.onDeviceProvisioned();
1894 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001895 }
Michael Jurkafff56142012-11-28 16:51:00 -08001896 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001897 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -08001898 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
1899 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001900 }
1901 }
1902
Jim Millerbbf1a742012-07-17 18:30:30 -07001903 /**
1904 * Handle {@link #MSG_PHONE_STATE_CHANGED}
1905 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001906 private void handlePhoneStateChanged(String newState) {
Jim Millerc23024d2010-02-24 15:37:00 -08001907 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001908 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
1909 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
1910 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
1911 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
1912 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
1913 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
1914 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001915 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001916 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1917 if (cb != null) {
1918 cb.onPhoneStateChanged(mPhoneState);
1919 }
Jim Millerc23024d2010-02-24 15:37:00 -08001920 }
1921 }
1922
Jim Millerbbf1a742012-07-17 18:30:30 -07001923 /**
1924 * Handle {@link #MSG_RINGER_MODE_CHANGED}
1925 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001926 private void handleRingerModeChange(int mode) {
Jim Miller47088bb2009-11-24 00:40:16 -08001927 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001928 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -07001929 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001930 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1931 if (cb != null) {
1932 cb.onRingerModeChanged(mode);
1933 }
Jim Miller47088bb2009-11-24 00:40:16 -08001934 }
1935 }
1936
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001937 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001938 * Handle {@link #MSG_TIME_UPDATE}
1939 */
1940 private void handleTimeUpdate() {
1941 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001942 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001943 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1944 if (cb != null) {
1945 cb.onTimeChanged();
1946 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001947 }
1948 }
1949
1950 /**
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05001951 * Handle (@line #MSG_TIMEZONE_UPDATE}
1952 */
1953 private void handleTimeZoneUpdate(String timeZone) {
1954 if (DEBUG) Log.d(TAG, "handleTimeZoneUpdate");
1955 for (int i = 0; i < mCallbacks.size(); i++) {
1956 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1957 if (cb != null) {
1958 cb.onTimeZoneChanged(TimeZone.getTimeZone(timeZone));
1959 // Also notify callbacks about time change to remain compatible.
1960 cb.onTimeChanged();
1961 }
1962 }
1963 }
1964
1965 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001966 * Handle {@link #MSG_BATTERY_UPDATE}
1967 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001968 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001969 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001970 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
1971 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07001972 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001973 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001974 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1975 if (cb != null) {
1976 cb.onRefreshBatteryInfo(status);
1977 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001978 }
1979 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001980 }
1981
1982 /**
Bill Linef81cbd2018-07-05 17:48:49 +08001983 * Handle Telephony status during Boot for CarrierText display policy
1984 */
1985 @VisibleForTesting
1986 void updateTelephonyCapable(boolean capable){
1987 if (capable == mTelephonyCapable) {
1988 return;
1989 }
1990 mTelephonyCapable = capable;
1991 for (WeakReference<KeyguardUpdateMonitorCallback> ref : mCallbacks) {
1992 KeyguardUpdateMonitorCallback cb = ref.get();
1993 if (cb != null) {
1994 cb.onTelephonyCapable(mTelephonyCapable);
1995 }
1996 }
1997 }
1998
1999 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002000 * Handle {@link #MSG_SIM_STATE_CHANGE}
2001 */
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08002002 @VisibleForTesting
Adrian Roos30a2ae62018-04-25 19:09:50 +02002003 void handleSimStateChange(int subId, int slotId, State state) {
2004 checkIsHandlerThread();
Jim Miller52a61332014-11-12 19:29:51 -08002005 if (DEBUG_SIM_STATES) {
2006 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
2007 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002008 }
2009
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002010 boolean becameAbsent = false;
Wink Savillea54bf652014-12-11 13:37:50 -08002011 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08002012 Log.w(TAG, "invalid subId in handleSimStateChange()");
andychou695a7602019-05-16 23:14:00 +08002013 /* Only handle No SIM(ABSENT) and Card Error(CARD_IO_ERROR) due to
2014 * handleServiceStateChange() handle other case */
Bill Linef81cbd2018-07-05 17:48:49 +08002015 if (state == State.ABSENT) {
2016 updateTelephonyCapable(true);
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002017 // Even though the subscription is not valid anymore, we need to notify that the
2018 // SIM card was removed so we can update the UI.
2019 becameAbsent = true;
Brad Ebingere6c6f722018-12-20 21:11:44 -08002020 for (SimData data : mSimDatas.values()) {
2021 // Set the SIM state of all SimData associated with that slot to ABSENT se we
2022 // do not move back into PIN/PUK locked and not detect the change below.
2023 if (data.slotId == slotId) {
2024 data.simState = State.ABSENT;
2025 }
2026 }
andychou695a7602019-05-16 23:14:00 +08002027 } else if (state == State.CARD_IO_ERROR) {
2028 updateTelephonyCapable(true);
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002029 } else {
2030 return;
Bill Linef81cbd2018-07-05 17:48:49 +08002031 }
Jim Miller52a61332014-11-12 19:29:51 -08002032 }
2033
2034 SimData data = mSimDatas.get(subId);
2035 final boolean changed;
2036 if (data == null) {
2037 data = new SimData(state, slotId, subId);
2038 mSimDatas.put(subId, data);
2039 changed = true; // no data yet; force update
2040 } else {
2041 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
2042 data.simState = state;
2043 data.subId = subId;
2044 data.slotId = slotId;
2045 }
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002046 if ((changed || becameAbsent) && state != State.UNKNOWN) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002047 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002048 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2049 if (cb != null) {
Jim Miller52a61332014-11-12 19:29:51 -08002050 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07002051 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002052 }
2053 }
2054 }
2055
Jim Millerbbf1a742012-07-17 18:30:30 -07002056 /**
Etan Cohen47051d82015-07-06 16:19:04 -07002057 * Handle {@link #MSG_SERVICE_STATE_CHANGE}
2058 */
Bill Linef81cbd2018-07-05 17:48:49 +08002059 @VisibleForTesting
2060 void handleServiceStateChange(int subId, ServiceState serviceState) {
Etan Cohen47051d82015-07-06 16:19:04 -07002061 if (DEBUG) {
2062 Log.d(TAG,
2063 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
2064 }
2065
2066 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2067 Log.w(TAG, "invalid subId in handleServiceStateChange()");
2068 return;
Bill Linef81cbd2018-07-05 17:48:49 +08002069 } else {
2070 updateTelephonyCapable(true);
Etan Cohen47051d82015-07-06 16:19:04 -07002071 }
2072
2073 mServiceStates.put(subId, serviceState);
2074
2075 for (int j = 0; j < mCallbacks.size(); j++) {
2076 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
2077 if (cb != null) {
2078 cb.onRefreshCarrierInfo();
2079 }
2080 }
2081 }
2082
Lucas Dupinf8463ee2018-06-11 16:18:15 -07002083 public boolean isKeyguardVisible() {
2084 return mKeyguardIsVisible;
2085 }
2086
Etan Cohen47051d82015-07-06 16:19:04 -07002087 /**
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002088 * Notifies that the visibility state of Keyguard has changed.
2089 *
2090 * <p>Needs to be called from the main thread.
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002091 */
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002092 public void onKeyguardVisibilityChanged(boolean showing) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002093 checkIsHandlerThread();
Kevin Chynb4514d22019-04-15 13:47:25 -07002094 Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002095 mKeyguardIsVisible = showing;
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002096 for (int i = 0; i < mCallbacks.size(); i++) {
2097 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2098 if (cb != null) {
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002099 cb.onKeyguardVisibilityChangedRaw(showing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002100 }
2101 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002102 updateBiometricListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002103 }
2104
Brian Colonna7fce3802013-09-17 15:51:32 -04002105 /**
Selim Cinek1fcafc42015-07-20 14:39:25 -07002106 * Handle {@link #MSG_KEYGUARD_RESET}
2107 */
2108 private void handleKeyguardReset() {
2109 if (DEBUG) Log.d(TAG, "handleKeyguardReset");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002110 updateBiometricListeningState();
Jorim Jaggi031f7952016-09-01 16:39:26 -07002111 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
2112 }
2113
2114 private boolean resolveNeedsSlowUnlockTransition() {
2115 if (mUserManager.isUserUnlocked(getCurrentUser())) {
2116 return false;
2117 }
2118 Intent homeIntent = new Intent(Intent.ACTION_MAIN)
2119 .addCategory(Intent.CATEGORY_HOME);
2120 ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(homeIntent,
2121 0 /* flags */);
2122 return FALLBACK_HOME_COMPONENT.equals(resolveInfo.getComponentInfo().getComponentName());
Selim Cinek1fcafc42015-07-20 14:39:25 -07002123 }
2124
2125 /**
Adrian Roosb6011622014-05-14 15:52:53 +02002126 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
2127 * @see #sendKeyguardBouncerChanged(boolean)
2128 */
2129 private void handleKeyguardBouncerChanged(int bouncer) {
2130 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
2131 boolean isBouncer = (bouncer == 1);
2132 mBouncer = isBouncer;
2133 for (int i = 0; i < mCallbacks.size(); i++) {
2134 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2135 if (cb != null) {
2136 cb.onKeyguardBouncerChanged(isBouncer);
2137 }
2138 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002139 updateBiometricListeningState();
Adrian Roosb6011622014-05-14 15:52:53 +02002140 }
2141
2142 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04002143 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
2144 */
2145 private void handleReportEmergencyCallAction() {
2146 for (int i = 0; i < mCallbacks.size(); i++) {
2147 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2148 if (cb != null) {
2149 cb.onEmergencyCallAction();
2150 }
2151 }
2152 }
2153
Lucas Dupin4272f442018-01-13 22:00:35 -08002154 private boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002155 final boolean nowPluggedIn = current.isPluggedIn();
2156 final boolean wasPluggedIn = old.isPluggedIn();
Lucas Dupin4272f442018-01-13 22:00:35 -08002157 final boolean stateChangedWhilePluggedIn = wasPluggedIn && nowPluggedIn
Jim Miller16464b82011-10-20 21:10:13 -07002158 && (old.status != current.status);
2159
2160 // change in plug state is always interesting
2161 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002162 return true;
2163 }
2164
Lucas Dupin3fcdd472018-01-19 19:06:45 -08002165 // change in battery level
2166 if (old.level != current.level) {
Jim Miller16464b82011-10-20 21:10:13 -07002167 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002168 }
Adrian Roos76dc5a52015-07-21 16:20:36 -07002169
2170 // change in charging current while plugged in
Adrian Roos0c859ae2015-11-23 16:47:50 -08002171 if (nowPluggedIn && current.maxChargingWattage != old.maxChargingWattage) {
Adrian Roos76dc5a52015-07-21 16:20:36 -07002172 return true;
2173 }
2174
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002175 return false;
2176 }
2177
2178 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07002179 * Remove the given observer's callback.
2180 *
Jim Miller6212cc02012-09-05 17:35:31 -07002181 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002182 */
Jim Miller6212cc02012-09-05 17:35:31 -07002183 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002184 checkIsHandlerThread();
Jim Miller6212cc02012-09-05 17:35:31 -07002185 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
2186 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
2187 if (mCallbacks.get(i).get() == callback) {
2188 mCallbacks.remove(i);
2189 }
2190 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002191 }
2192
2193 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002194 * Register to receive notifications about general keyguard information
2195 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07002196 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002197 */
Jim Millerbbf1a742012-07-17 18:30:30 -07002198 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002199 checkIsHandlerThread();
Jim Miller6212cc02012-09-05 17:35:31 -07002200 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
2201 // Prevent adding duplicate callbacks
2202 for (int i = 0; i < mCallbacks.size(); i++) {
2203 if (mCallbacks.get(i).get() == callback) {
2204 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
2205 new Exception("Called by"));
2206 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07002207 }
2208 }
Jim Miller6212cc02012-09-05 17:35:31 -07002209 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
2210 removeCallback(null); // remove unused references
2211 sendUpdates(callback);
2212 }
2213
Lucas Dupinc12fad32019-05-14 20:59:17 +00002214 public boolean isSwitchingUser() {
2215 return mSwitchingUser;
2216 }
2217
Adrian Roos30a2ae62018-04-25 19:09:50 +02002218 @AnyThread
Evan Rosky18396452016-07-27 15:19:37 -07002219 public void setSwitchingUser(boolean switching) {
Lucas Dupinc12fad32019-05-14 20:59:17 +00002220 mSwitchingUser = switching;
Selim Cinekbbe19242017-12-08 15:42:08 -08002221 // Since this comes in on a binder thread, we need to post if first
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002222 mHandler.post(mUpdateBiometricListeningState);
Evan Rosky18396452016-07-27 15:19:37 -07002223 }
2224
Jim Miller6212cc02012-09-05 17:35:31 -07002225 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
2226 // Notify listener of the current state
2227 callback.onRefreshBatteryInfo(mBatteryStatus);
2228 callback.onTimeChanged();
2229 callback.onRingerModeChanged(mRingMode);
2230 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05002231 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07002232 callback.onClockVisibilityChanged();
Lucas Dupin16cfe452018-02-08 13:14:50 -08002233 callback.onKeyguardVisibilityChangedRaw(mKeyguardIsVisible);
Bill Linef81cbd2018-07-05 17:48:49 +08002234 callback.onTelephonyCapable(mTelephonyCapable);
Jim Miller52a61332014-11-12 19:29:51 -08002235 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
2236 final SimData state = data.getValue();
2237 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
2238 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002239 }
2240
Selim Cinek1fcafc42015-07-20 14:39:25 -07002241 public void sendKeyguardReset() {
2242 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
2243 }
2244
Adrian Roosb6011622014-05-14 15:52:53 +02002245 /**
2246 * @see #handleKeyguardBouncerChanged(int)
2247 */
2248 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
2249 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
2250 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
2251 message.arg1 = showingBouncer ? 1 : 0;
2252 message.sendToTarget();
2253 }
2254
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002255 /**
Jim Miller90d5d462011-11-17 16:57:01 -08002256 * Report that the user successfully entered the SIM PIN or PUK/SIM PIN so we
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002257 * have the information earlier than waiting for the intent
2258 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08002259 *
2260 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
2261 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002262 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02002263 @MainThread
Jim Miller52a61332014-11-12 19:29:51 -08002264 public void reportSimUnlocked(int subId) {
2265 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
Sanket Padawe7e460252017-03-10 16:18:20 -08002266 int slotId = SubscriptionManager.getSlotIndex(subId);
Jim Miller52a61332014-11-12 19:29:51 -08002267 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002268 }
2269
Brian Colonna7fce3802013-09-17 15:51:32 -04002270 /**
2271 * Report that the emergency call button has been pressed and the emergency dialer is
2272 * about to be displayed.
2273 *
2274 * @param bypassHandler runs immediately.
2275 *
2276 * NOTE: Must be called from UI thread if bypassHandler == true.
2277 */
2278 public void reportEmergencyCallAction(boolean bypassHandler) {
2279 if (!bypassHandler) {
2280 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
2281 } else {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002282 checkIsHandlerThread();
Brian Colonna7fce3802013-09-17 15:51:32 -04002283 handleReportEmergencyCallAction();
2284 }
2285 }
2286
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002287 /**
2288 * @return Whether the device is provisioned (whether they have gone through
2289 * the setup wizard)
2290 */
2291 public boolean isDeviceProvisioned() {
2292 return mDeviceProvisioned;
2293 }
2294
Kensuke Matsui21d1bf12017-03-14 13:27:20 +09002295 public ServiceState getServiceState(int subId) {
2296 return mServiceStates.get(subId);
2297 }
2298
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002299 public void clearBiometricRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07002300 mUserFingerprintAuthenticated.clear();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002301 mUserFaceAuthenticated.clear();
2302 mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FINGERPRINT);
2303 mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FACE);
Jim Millerf41fc962014-06-18 16:33:51 -07002304 }
2305
Jim Miller52a61332014-11-12 19:29:51 -08002306 public boolean isSimPinVoiceSecure() {
2307 // TODO: only count SIMs that handle voice
2308 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07002309 }
2310
Lucas Dupin7156bc72019-05-03 19:37:39 -07002311 /**
2312 * If any SIM cards are currently secure.
2313 * @see #isSimPinSecure(State)
2314 */
Jim Millerdcb3d842012-08-23 19:18:12 -07002315 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08002316 // True if any SIM is pin secure
2317 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
2318 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
2319 }
2320 return false;
2321 }
2322
Jason Monk9ff69bd2014-12-02 16:43:17 -05002323 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08002324 if (mSimDatas.containsKey(subId)) {
2325 return mSimDatas.get(subId).simState;
2326 } else {
2327 return State.UNKNOWN;
2328 }
2329 }
2330
Winson Chung67f5c8b2018-09-24 12:09:19 -07002331 private final TaskStackChangeListener
2332 mTaskStackListener = new TaskStackChangeListener() {
Kevin Chyn2fefd462017-04-28 12:18:19 -07002333 @Override
2334 public void onTaskStackChangedBackground() {
2335 try {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002336 ActivityManager.StackInfo info = ActivityTaskManager.getService().getStackInfo(
Wale Ogunwale68278562017-09-23 17:13:55 -07002337 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
Kevin Chyn2fefd462017-04-28 12:18:19 -07002338 if (info == null) {
2339 return;
2340 }
2341 mHandler.sendMessage(mHandler.obtainMessage(MSG_ASSISTANT_STACK_CHANGED,
2342 info.visible));
2343 } catch (RemoteException e) {
2344 Log.e(TAG, "unable to check task stack", e);
2345 }
2346 }
2347 };
2348
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002349 /**
Richard Choue0381b82018-04-24 03:48:59 +00002350 * @return true if and only if the state has changed for the specified {@code slotId}
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002351 */
Richard Choue0381b82018-04-24 03:48:59 +00002352 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08002353
2354 // This is awful. It exists because there are two APIs for getting the SIM status
2355 // that don't return the complete set of values and have different types. In Keyguard we
2356 // need IccCardConstants, but TelephonyManager would only give us
2357 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08002358 final TelephonyManager tele = TelephonyManager.from(mContext);
Richard Choue0381b82018-04-24 03:48:59 +00002359 int simState = tele.getSimState(slotId);
2360 State state;
2361 try {
2362 state = State.intToState(simState);
2363 } catch(IllegalArgumentException ex) {
2364 Log.w(TAG, "Unknown sim state: " + simState);
2365 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05002366 }
Richard Choue0381b82018-04-24 03:48:59 +00002367 SimData data = mSimDatas.get(subId);
2368 final boolean changed;
2369 if (data == null) {
2370 data = new SimData(state, slotId, subId);
2371 mSimDatas.put(subId, data);
2372 changed = true; // no data yet; force update
2373 } else {
2374 changed = data.simState != state;
2375 data.simState = state;
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002376 }
Richard Choue0381b82018-04-24 03:48:59 +00002377 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07002378 }
2379
Lucas Dupin7156bc72019-05-03 19:37:39 -07002380 /**
2381 * If the {@code state} is currently requiring a SIM PIN, PUK, or is disabled.
2382 */
Jim Millerdcb3d842012-08-23 19:18:12 -07002383 public static boolean isSimPinSecure(IccCardConstants.State state) {
Lucas Dupin7156bc72019-05-03 19:37:39 -07002384 return (state == IccCardConstants.State.PIN_REQUIRED
2385 || state == IccCardConstants.State.PUK_REQUIRED
2386 || state == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07002387 }
Jim Miller8f09fd22013-03-14 19:04:28 -07002388
2389 public DisplayClientState getCachedDisplayClientState() {
2390 return mDisplayClientState;
2391 }
Jim Miller20daffd2013-10-07 14:59:53 -07002392
2393 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
2394 // (KeyguardViewMediator, KeyguardHostView)
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002395 public void dispatchStartedWakingUp() {
2396 synchronized (this) {
2397 mDeviceInteractive = true;
2398 }
2399 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
2400 }
2401
Jorim Jaggi95e40382015-09-16 15:53:42 -07002402 public void dispatchStartedGoingToSleep(int why) {
2403 mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
2404 }
2405
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002406 public void dispatchFinishedGoingToSleep(int why) {
2407 synchronized(this) {
2408 mDeviceInteractive = false;
2409 }
2410 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
2411 }
2412
Jim Miller20daffd2013-10-07 14:59:53 -07002413 public void dispatchScreenTurnedOn() {
2414 synchronized (this) {
2415 mScreenOn = true;
2416 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07002417 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
Jim Miller20daffd2013-10-07 14:59:53 -07002418 }
2419
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002420 public void dispatchScreenTurnedOff() {
Jim Miller20daffd2013-10-07 14:59:53 -07002421 synchronized(this) {
2422 mScreenOn = false;
2423 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07002424 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
Jim Miller20daffd2013-10-07 14:59:53 -07002425 }
2426
Selim Cinek99415392016-09-09 14:58:41 -07002427 public void dispatchDreamingStarted() {
2428 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 1, 0));
2429 }
2430
2431 public void dispatchDreamingStopped() {
2432 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 0, 0));
2433 }
2434
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002435 public boolean isDeviceInteractive() {
2436 return mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -07002437 }
Jim Miller52a61332014-11-12 19:29:51 -08002438
Jorim Jaggi95e40382015-09-16 15:53:42 -07002439 public boolean isGoingToSleep() {
2440 return mGoingToSleep;
2441 }
2442
Jim Miller52a61332014-11-12 19:29:51 -08002443 /**
2444 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
2445 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08002446 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08002447 */
2448 public int getNextSubIdForState(State state) {
2449 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08002450 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08002451 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
2452 for (int i = 0; i < list.size(); i++) {
2453 final SubscriptionInfo info = list.get(i);
2454 final int id = info.getSubscriptionId();
Sanket Padawe7e460252017-03-10 16:18:20 -08002455 int slotId = SubscriptionManager.getSlotIndex(id);
Jim Miller52a61332014-11-12 19:29:51 -08002456 if (state == getSimState(id) && bestSlotId > slotId ) {
2457 resultId = id;
2458 bestSlotId = slotId;
2459 }
2460 }
2461 return resultId;
2462 }
2463
2464 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
2465 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
2466 for (int i = 0; i < list.size(); i++) {
2467 SubscriptionInfo info = list.get(i);
2468 if (subId == info.getSubscriptionId()) return info;
2469 }
2470 return null; // not found
2471 }
Jason Monkab525272015-07-13 17:02:49 -04002472
Alex Chauff7653d2018-02-01 17:18:08 +00002473 /**
2474 * @return a cached version of DevicePolicyManager.isLogoutEnabled()
2475 */
2476 public boolean isLogoutEnabled() {
2477 return mLogoutEnabled;
2478 }
2479
2480 private void updateLogoutEnabled() {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002481 checkIsHandlerThread();
Alex Chauff7653d2018-02-01 17:18:08 +00002482 boolean logoutEnabled = mDevicePolicyManager.isLogoutEnabled();
2483 if (mLogoutEnabled != logoutEnabled) {
2484 mLogoutEnabled = logoutEnabled;
2485 for (int i = 0; i < mCallbacks.size(); i++) {
2486 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2487 if (cb != null) {
2488 cb.onLogoutEnabledChanged();
2489 }
2490 }
2491 }
2492 }
2493
Adrian Roos30a2ae62018-04-25 19:09:50 +02002494 private void checkIsHandlerThread() {
2495 if (sDisableHandlerCheckForTesting) {
2496 return;
2497 }
2498 if (!mHandler.getLooper().isCurrentThread()) {
2499 Log.wtf(TAG, "must call on mHandler's thread "
2500 + mHandler.getLooper().getThread() + ", not " + Thread.currentThread());
2501 }
2502 }
2503
2504 /**
2505 * Turn off the handler check for testing.
2506 *
2507 * This is necessary because currently tests are not too careful about which thread they call
2508 * into this class on.
2509 *
2510 * Note that this must be called before scheduling any work involving KeyguardUpdateMonitor
2511 * instances.
2512 *
2513 * TODO: fix the tests and remove this.
2514 */
2515 @VisibleForTesting
2516 public static void disableHandlerCheckForTesting(Instrumentation instrumentation) {
2517 Preconditions.checkNotNull(instrumentation, "Must only call this method in tests!");
2518 // Don't need synchronization here *if* the callers follow the contract and call this only
2519 // before scheduling work for KeyguardUpdateMonitor on other threads, because the scheduling
2520 // of that work forces a happens-before relationship.
2521 sDisableHandlerCheckForTesting = true;
2522 }
2523
Jason Monkab525272015-07-13 17:02:49 -04002524 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2525 pw.println("KeyguardUpdateMonitor state:");
2526 pw.println(" SIM States:");
2527 for (SimData data : mSimDatas.values()) {
2528 pw.println(" " + data.toString());
2529 }
2530 pw.println(" Subs:");
2531 if (mSubscriptionInfo != null) {
2532 for (int i = 0; i < mSubscriptionInfo.size(); i++) {
2533 pw.println(" " + mSubscriptionInfo.get(i));
2534 }
2535 }
2536 pw.println(" Service states:");
2537 for (int subId : mServiceStates.keySet()) {
2538 pw.println(" " + subId + "=" + mServiceStates.get(subId));
2539 }
Jim Millerd72d5ac2015-09-29 18:55:32 -07002540 if (mFpm != null && mFpm.isHardwareDetected()) {
2541 final int userId = ActivityManager.getCurrentUser();
2542 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
2543 pw.println(" Fingerprint state (user=" + userId + ")");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002544 pw.println(" allowed=" + isUnlockingWithBiometricAllowed());
Jim Millerd72d5ac2015-09-29 18:55:32 -07002545 pw.println(" auth'd=" + mUserFingerprintAuthenticated.get(userId));
2546 pw.println(" authSinceBoot="
2547 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
2548 pw.println(" disabled(DPM)=" + isFingerprintDisabled(userId));
2549 pw.println(" possible=" + isUnlockWithFingerprintPossible(userId));
Adrian Roos2aaf9442018-11-20 16:57:33 +01002550 pw.println(" listening: actual=" + mFingerprintRunningState
2551 + " expected=" + (shouldListenForFingerprint() ? 1 : 0));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002552 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002553 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
2554 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07002555 if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002556 final int userId = ActivityManager.getCurrentUser();
2557 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
2558 pw.println(" Face authentication state (user=" + userId + ")");
2559 pw.println(" allowed=" + isUnlockingWithBiometricAllowed());
2560 pw.println(" auth'd=" + mUserFaceAuthenticated.get(userId));
2561 pw.println(" authSinceBoot="
2562 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
2563 pw.println(" disabled(DPM)=" + isFaceDisabled(userId));
2564 pw.println(" possible=" + isUnlockWithFacePossible(userId));
2565 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
2566 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
Kevin Chynb7b54a62018-09-28 18:48:12 -07002567 pw.println(" enabledByUser=" + mFaceSettingEnabledForUser);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002568 }
Jason Monkab525272015-07-13 17:02:49 -04002569 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002570}