blob: 109f270063d6a1cc35a9b260ae1c29018399c900 [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;
Fabian Kozynskiccde55d2019-06-26 10:06:09 -040031import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070032
Lucas Dupin8eec2682019-07-01 16:41:17 -070033import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
34import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
35import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
36import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
37import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
38
Adrian Roos30a2ae62018-04-25 19:09:50 +020039import android.annotation.AnyThread;
40import android.annotation.MainThread;
Jorim Jaggiccdfa932015-04-13 16:29:48 -070041import android.app.ActivityManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070042import android.app.ActivityTaskManager;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020043import android.app.AlarmManager;
Adrian Roos30a2ae62018-04-25 19:09:50 +020044import android.app.Instrumentation;
Jim Miller8f09fd22013-03-14 19:04:28 -070045import android.app.PendingIntent;
Sudheer Shanka2c4522c2016-08-27 20:53:28 -070046import android.app.UserSwitchObserver;
Jim Millerb0304762012-03-13 20:01:25 -070047import android.app.admin.DevicePolicyManager;
Adrian Roos46842d92014-03-27 14:58:03 +010048import android.app.trust.TrustManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080049import android.content.BroadcastReceiver;
Jorim Jaggi031f7952016-09-01 16:39:26 -070050import android.content.ComponentName;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080051import android.content.Context;
52import android.content.Intent;
53import android.content.IntentFilter;
Adrian Roosca8a2162017-08-17 19:00:58 +020054import android.content.pm.IPackageManager;
Jorim Jaggi031f7952016-09-01 16:39:26 -070055import android.content.pm.PackageManager;
56import android.content.pm.ResolveInfo;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080057import android.database.ContentObserver;
Kevin Chynb7b54a62018-09-28 18:48:12 -070058import android.hardware.biometrics.BiometricManager;
Kevin Chyn56233ab2018-09-20 17:10:57 -070059import android.hardware.biometrics.BiometricSourceType;
Kevin Chynb7b54a62018-09-28 18:48:12 -070060import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
Gilad Brettercb51b8b2018-03-22 17:04:51 +020061import android.hardware.face.FaceManager;
Jorim Jaggi86bed402015-08-20 18:20:02 -070062import android.hardware.fingerprint.FingerprintManager;
63import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
64import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
Jim Miller47088bb2009-11-24 00:40:16 -080065import android.media.AudioManager;
Jim Miller79a444a2011-02-15 15:02:11 -080066import android.os.BatteryManager;
Jim Miller9f0753f2015-03-23 23:59:22 -070067import android.os.CancellationSignal;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080068import android.os.Handler;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070069import android.os.IRemoteCallback;
Jason Monk7bb59302018-05-10 19:38:18 -070070import android.os.Looper;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080071import android.os.Message;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070072import android.os.RemoteException;
Adrian Roosca8a2162017-08-17 19:00:58 +020073import android.os.ServiceManager;
Nick Desaulniers1d396752016-07-25 15:05:33 -070074import android.os.Trace;
Amith Yamasanie8e93a12013-05-09 18:12:30 -070075import android.os.UserHandle;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070076import android.os.UserManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080077import android.provider.Settings;
Kevin Chyn36778ff2017-09-07 19:55:38 -070078import android.service.dreams.DreamService;
79import android.service.dreams.IDreamManager;
Fabian Kozynskiccde55d2019-06-26 10:06:09 -040080import android.telephony.PhoneStateListener;
Etan Cohen47051d82015-07-06 16:19:04 -070081import android.telephony.ServiceState;
Jim Miller52a61332014-11-12 19:29:51 -080082import android.telephony.SubscriptionInfo;
Jim Miller52a61332014-11-12 19:29:51 -080083import android.telephony.SubscriptionManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -080084import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Jim Millerc23024d2010-02-24 15:37:00 -080085import android.telephony.TelephonyManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080086import android.util.Log;
Adrian Roos46842d92014-03-27 14:58:03 +010087import android.util.SparseBooleanArray;
88
Lucas Dupin7517b5d2017-08-22 12:51:25 -070089import com.android.internal.annotations.VisibleForTesting;
Jorim Jaggi86bed402015-08-20 18:20:02 -070090import com.android.internal.telephony.IccCardConstants;
91import com.android.internal.telephony.IccCardConstants.State;
92import com.android.internal.telephony.PhoneConstants;
93import com.android.internal.telephony.TelephonyIntents;
Adrian Roos30a2ae62018-04-25 19:09:50 +020094import com.android.internal.util.Preconditions;
Adrian Roosb5e47222015-08-14 15:53:06 -070095import com.android.internal.widget.LockPatternUtils;
Bill Linef81cbd2018-07-05 17:48:49 +080096import com.android.settingslib.WirelessUtils;
Winson Chung2cf6ad82017-11-09 17:36:59 -080097import com.android.systemui.shared.system.ActivityManagerWrapper;
Winson Chung67f5c8b2018-09-24 12:09:19 -070098import com.android.systemui.shared.system.TaskStackChangeListener;
Lucas Dupin9e484aa2019-06-24 13:38:00 -070099import com.android.systemui.statusbar.phone.KeyguardBypassController;
Kevin Chyn1123ba72018-10-26 10:34:06 -0700100
Kevin Chyn36778ff2017-09-07 19:55:38 -0700101import com.google.android.collect.Lists;
102
Jason Monkab525272015-07-13 17:02:49 -0400103import java.io.FileDescriptor;
104import java.io.PrintWriter;
Jim Millerdcb3d842012-08-23 19:18:12 -0700105import java.lang.ref.WeakReference;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800106import java.util.ArrayList;
Jim Miller52a61332014-11-12 19:29:51 -0800107import java.util.HashMap;
108import java.util.List;
109import java.util.Map.Entry;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500110import java.util.TimeZone;
Lucas Dupin3d053532019-01-29 12:35:22 -0800111import java.util.function.Consumer;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800112
113/**
114 * Watches for updates that may be interesting to the keyguard, and provides
115 * the up to date information as well as a registration for callbacks that care
116 * to be updated.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800117 */
Adrian Roos46842d92014-03-27 14:58:03 +0100118public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800119
Jim Millerbbf1a742012-07-17 18:30:30 -0700120 private static final String TAG = "KeyguardUpdateMonitor";
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100121 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller52a61332014-11-12 19:29:51 -0800122 private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700123 private static final boolean DEBUG_FACE = true;
Jim Millerbbf1a742012-07-17 18:30:30 -0700124 private static final int LOW_BATTERY_THRESHOLD = 20;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800125
Jorim Jaggie7b12522014-08-06 16:41:21 +0200126 private static final String ACTION_FACE_UNLOCK_STARTED
127 = "com.android.facelock.FACE_UNLOCK_STARTED";
128 private static final String ACTION_FACE_UNLOCK_STOPPED
129 = "com.android.facelock.FACE_UNLOCK_STOPPED";
130
Jim Millerbbf1a742012-07-17 18:30:30 -0700131 // Callback messages
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800132 private static final int MSG_TIME_UPDATE = 301;
133 private static final int MSG_BATTERY_UPDATE = 302;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800134 private static final int MSG_SIM_STATE_CHANGE = 304;
Jim Miller47088bb2009-11-24 00:40:16 -0800135 private static final int MSG_RINGER_MODE_CHANGED = 305;
Jim Millerc23024d2010-02-24 15:37:00 -0800136 private static final int MSG_PHONE_STATE_CHANGED = 306;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700137 private static final int MSG_DEVICE_PROVISIONED = 308;
Jim Miller57375342012-09-09 15:20:31 -0700138 private static final int MSG_DPM_STATE_CHANGED = 309;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500139 private static final int MSG_USER_SWITCHING = 310;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700140 private static final int MSG_KEYGUARD_RESET = 312;
Jim Millerf41fc962014-06-18 16:33:51 -0700141 private static final int MSG_BOOT_COMPLETED = 313;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500142 private static final int MSG_USER_SWITCH_COMPLETE = 314;
Jim Millerf41fc962014-06-18 16:33:51 -0700143 private static final int MSG_USER_INFO_CHANGED = 317;
144 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700145 private static final int MSG_STARTED_WAKING_UP = 319;
146 private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700147 private static final int MSG_STARTED_GOING_TO_SLEEP = 321;
Adrian Roosb6011622014-05-14 15:52:53 +0200148 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700149 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
150 private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
Jason Monk052082c2015-06-11 11:35:23 -0400151 private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
Etan Cohen47051d82015-07-06 16:19:04 -0700152 private static final int MSG_SERVICE_STATE_CHANGE = 330;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700153 private static final int MSG_SCREEN_TURNED_ON = 331;
154 private static final int MSG_SCREEN_TURNED_OFF = 332;
Selim Cinek99415392016-09-09 14:58:41 -0700155 private static final int MSG_DREAMING_STATE_CHANGED = 333;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700156 private static final int MSG_USER_UNLOCKED = 334;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700157 private static final int MSG_ASSISTANT_STACK_CHANGED = 335;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200158 private static final int MSG_BIOMETRIC_AUTHENTICATION_CONTINUE = 336;
Alex Chauff7653d2018-02-01 17:18:08 +0000159 private static final int MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED = 337;
Bill Linef81cbd2018-07-05 17:48:49 +0800160 private static final int MSG_TELEPHONY_CAPABLE = 338;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500161 private static final int MSG_TIMEZONE_UPDATE = 339;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800162
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200163 /** Biometric authentication state: Not listening. */
164 private static final int BIOMETRIC_STATE_STOPPED = 0;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700165
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200166 /** Biometric authentication state: Listening. */
167 private static final int BIOMETRIC_STATE_RUNNING = 1;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700168
169 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200170 * Biometric authentication: Cancelling and waiting for the relevant biometric service to
Jorim Jaggi86bed402015-08-20 18:20:02 -0700171 * send us the confirmation that cancellation has happened.
172 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200173 private static final int BIOMETRIC_STATE_CANCELLING = 2;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700174
175 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200176 * Biometric state: During cancelling we got another request to start listening, so when we
Jorim Jaggi86bed402015-08-20 18:20:02 -0700177 * receive the cancellation done signal, we should start listening again.
178 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200179 private static final int BIOMETRIC_STATE_CANCELLING_RESTARTING = 3;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700180
Lucas Dupin51996bb2019-05-16 17:56:43 -0700181 private static final int BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED = -1;
182 public static final int BIOMETRIC_HELP_FACE_NOT_RECOGNIZED = -2;
183
Adrian Roos0c859ae2015-11-23 16:47:50 -0800184 private static final int DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT = 5000000;
185
Jorim Jaggi031f7952016-09-01 16:39:26 -0700186 private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName(
187 "com.android.settings", "com.android.settings.FallbackHome");
188
Adrian Roosca8a2162017-08-17 19:00:58 +0200189
190 /**
191 * If true, the system is in the half-boot-to-decryption-screen state.
192 * Prudently disable lockscreen.
193 */
194 public static final boolean CORE_APPS_ONLY;
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700195
Adrian Roosca8a2162017-08-17 19:00:58 +0200196 static {
197 try {
198 CORE_APPS_ONLY = IPackageManager.Stub.asInterface(
199 ServiceManager.getService("package")).isOnlyCoreApps();
200 } catch (RemoteException e) {
201 throw e.rethrowFromSystemServer();
202 }
203 }
204
Jim Millerdcb3d842012-08-23 19:18:12 -0700205 private static KeyguardUpdateMonitor sInstance;
206
Jim Millerbbf1a742012-07-17 18:30:30 -0700207 private final Context mContext;
Kevin Chynfdfd2d32019-03-01 14:52:15 -0800208 private final boolean mIsPrimaryUser;
Jim Miller52a61332014-11-12 19:29:51 -0800209 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
Etan Cohen47051d82015-07-06 16:19:04 -0700210 HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700211
Jim Millerbbf1a742012-07-17 18:30:30 -0700212 private int mRingMode;
213 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400214 private boolean mKeyguardIsVisible;
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700215 private boolean mKeyguardGoingAway;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700216 private boolean mGoingToSleep;
Adrian Roosb6011622014-05-14 15:52:53 +0200217 private boolean mBouncer;
Lucas Dupine0516d52019-02-05 17:54:06 -0500218 private boolean mAuthInterruptActive;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800219 private boolean mBootCompleted;
Jorim Jaggi031f7952016-09-01 16:39:26 -0700220 private boolean mNeedsSlowUnlockTransition;
Jorim Jaggid11d1a92016-08-16 16:02:32 -0700221 private boolean mHasLockscreenWallpaper;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700222 private boolean mAssistantVisible;
223 private boolean mKeyguardOccluded;
Kevin Chyn6951d3d2019-06-10 14:07:13 -0700224 private boolean mSecureCameraLaunched;
Bill Linef81cbd2018-07-05 17:48:49 +0800225 @VisibleForTesting
226 protected boolean mTelephonyCapable;
Jim Millerbbf1a742012-07-17 18:30:30 -0700227
Jim Millerdcb3d842012-08-23 19:18:12 -0700228 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700229 private boolean mDeviceProvisioned;
230
Jim Millerdcb3d842012-08-23 19:18:12 -0700231 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700232 private BatteryStatus mBatteryStatus;
233
Lucas Dupin3d053532019-01-29 12:35:22 -0800234 @VisibleForTesting
235 protected StrongAuthTracker mStrongAuthTracker;
Jim Millerbbf1a742012-07-17 18:30:30 -0700236
Jim Miller6212cc02012-09-05 17:35:31 -0700237 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700238 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800239 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700240
Brian Colonnaa5239892013-04-15 11:45:40 -0400241 private boolean mSwitchingUser;
242
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700243 private boolean mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -0700244 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800245 private SubscriptionManager mSubscriptionManager;
246 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700247 private TrustManager mTrustManager;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700248 private UserManager mUserManager;
Lucas Dupin9e484aa2019-06-24 13:38:00 -0700249 private KeyguardBypassController mKeyguardBypassController;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200250 private int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
251 private int mFaceRunningState = BIOMETRIC_STATE_STOPPED;
Michal Karpinskic52f8672016-11-18 11:32:45 +0000252 private LockPatternUtils mLockPatternUtils;
Kevin Chyn36778ff2017-09-07 19:55:38 -0700253 private final IDreamManager mDreamManager;
254 private boolean mIsDreaming;
Alex Chauff7653d2018-02-01 17:18:08 +0000255 private final DevicePolicyManager mDevicePolicyManager;
256 private boolean mLogoutEnabled;
Lucas Dupinca88e5f2019-05-14 16:11:08 -0700257 // If the user long pressed the lock icon, disabling face auth for the current session.
258 private boolean mLockIconPressed;
Jim Miller20daffd2013-10-07 14:59:53 -0700259
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700260 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200261 * Short delay before restarting biometric authentication after a successful try
262 * This should be slightly longer than the time between on<biometric>Authenticated
263 * (e.g. onFingerprintAuthenticated) and setKeyguardGoingAway(true).
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700264 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200265 private static final int BIOMETRIC_CONTINUE_DELAY_MS = 500;
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700266
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700267 // If the HAL dies or is unable to authenticate, keyguard should retry after a short delay
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200268 private int mHardwareFingerprintUnavailableRetryCount = 0;
269 private int mHardwareFaceUnavailableRetryCount = 0;
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700270 private static final int HAL_ERROR_RETRY_TIMEOUT = 500; // ms
271 private static final int HAL_ERROR_RETRY_MAX = 10;
Kevin Chyn0c45b072017-04-24 16:27:11 -0700272
Jason Monk7bb59302018-05-10 19:38:18 -0700273 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700274 @Override
275 public void handleMessage(Message msg) {
276 switch (msg.what) {
277 case MSG_TIME_UPDATE:
278 handleTimeUpdate();
279 break;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500280 case MSG_TIMEZONE_UPDATE:
281 handleTimeZoneUpdate((String) msg.obj);
282 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700283 case MSG_BATTERY_UPDATE:
284 handleBatteryUpdate((BatteryStatus) msg.obj);
285 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700286 case MSG_SIM_STATE_CHANGE:
Jim Miller52a61332014-11-12 19:29:51 -0800287 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700288 break;
289 case MSG_RINGER_MODE_CHANGED:
290 handleRingerModeChange(msg.arg1);
291 break;
292 case MSG_PHONE_STATE_CHANGED:
Adrian Roosb6011622014-05-14 15:52:53 +0200293 handlePhoneStateChanged((String) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700294 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700295 case MSG_DEVICE_PROVISIONED:
296 handleDeviceProvisioned();
297 break;
298 case MSG_DPM_STATE_CHANGED:
299 handleDevicePolicyManagerStateChanged();
300 break;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500301 case MSG_USER_SWITCHING:
Adrian Roosb6011622014-05-14 15:52:53 +0200302 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
Chris Wrenf41c61b2012-11-29 15:19:54 -0500303 break;
304 case MSG_USER_SWITCH_COMPLETE:
305 handleUserSwitchComplete(msg.arg1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700306 break;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700307 case MSG_KEYGUARD_RESET:
308 handleKeyguardReset();
309 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200310 case MSG_KEYGUARD_BOUNCER_CHANGED:
311 handleKeyguardBouncerChanged(msg.arg1);
312 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800313 case MSG_BOOT_COMPLETED:
314 handleBootCompleted();
315 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700316 case MSG_USER_INFO_CHANGED:
317 handleUserInfoChanged(msg.arg1);
318 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400319 case MSG_REPORT_EMERGENCY_CALL_ACTION:
320 handleReportEmergencyCallAction();
321 break;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700322 case MSG_STARTED_GOING_TO_SLEEP:
323 handleStartedGoingToSleep(msg.arg1);
324 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700325 case MSG_FINISHED_GOING_TO_SLEEP:
326 handleFinishedGoingToSleep(msg.arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700327 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700328 case MSG_STARTED_WAKING_UP:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700329 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_STARTED_WAKING_UP");
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700330 handleStartedWakingUp();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700331 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -0700332 break;
Jorim Jaggie7b12522014-08-06 16:41:21 +0200333 case MSG_FACE_UNLOCK_STATE_CHANGED:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700334 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_FACE_UNLOCK_STATE_CHANGED");
Adrian Roos4a410172014-08-20 17:41:44 +0200335 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
Nick Desaulniers1d396752016-07-25 15:05:33 -0700336 Trace.endSection();
Jorim Jaggie7b12522014-08-06 16:41:21 +0200337 break;
Jim Miller52a61332014-11-12 19:29:51 -0800338 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
339 handleSimSubscriptionInfoChanged();
340 break;
Jason Monk052082c2015-06-11 11:35:23 -0400341 case MSG_AIRPLANE_MODE_CHANGED:
342 handleAirplaneModeChanged();
343 break;
Etan Cohen47051d82015-07-06 16:19:04 -0700344 case MSG_SERVICE_STATE_CHANGE:
Bonian Chena7e9e8c2019-06-02 23:59:31 +0000345 handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
Etan Cohen47051d82015-07-06 16:19:04 -0700346 break;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700347 case MSG_SCREEN_TURNED_ON:
348 handleScreenTurnedOn();
349 break;
350 case MSG_SCREEN_TURNED_OFF:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700351 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_SCREEN_TURNED_ON");
Jorim Jaggif1518da2015-07-30 11:56:36 -0700352 handleScreenTurnedOff();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700353 Trace.endSection();
Jorim Jaggif1518da2015-07-30 11:56:36 -0700354 break;
Selim Cinek99415392016-09-09 14:58:41 -0700355 case MSG_DREAMING_STATE_CHANGED:
356 handleDreamingStateChanged(msg.arg1);
357 break;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700358 case MSG_USER_UNLOCKED:
359 handleUserUnlocked();
360 break;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700361 case MSG_ASSISTANT_STACK_CHANGED:
Lucas Dupin3d053532019-01-29 12:35:22 -0800362 setAssistantVisible((boolean) msg.obj);
Kevin Chyn2fefd462017-04-28 12:18:19 -0700363 break;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200364 case MSG_BIOMETRIC_AUTHENTICATION_CONTINUE:
365 updateBiometricListeningState();
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700366 break;
Alex Chauff7653d2018-02-01 17:18:08 +0000367 case MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED:
368 updateLogoutEnabled();
369 break;
Bill Linef81cbd2018-07-05 17:48:49 +0800370 case MSG_TELEPHONY_CAPABLE:
Lucas Dupin3d053532019-01-29 12:35:22 -0800371 updateTelephonyCapable((boolean) msg.obj);
Bill Linef81cbd2018-07-05 17:48:49 +0800372 break;
Jason Monk7bb59302018-05-10 19:38:18 -0700373 default:
374 super.handleMessage(msg);
375 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700376 }
377 }
378 };
379
Lucas Dupin7d95f152019-07-17 16:25:54 -0700380 private SparseBooleanArray mFaceSettingEnabledForUser = new SparseBooleanArray();
Kevin Chynb7b54a62018-09-28 18:48:12 -0700381 private BiometricManager mBiometricManager;
382 private IBiometricEnabledOnKeyguardCallback mBiometricEnabledCallback =
383 new IBiometricEnabledOnKeyguardCallback.Stub() {
384 @Override
Lucas Dupin7d95f152019-07-17 16:25:54 -0700385 public void onChanged(BiometricSourceType type, boolean enabled, int userId)
386 throws RemoteException {
Kevin Chynb7b54a62018-09-28 18:48:12 -0700387 if (type == BiometricSourceType.FACE) {
Lucas Dupin7d95f152019-07-17 16:25:54 -0700388 mFaceSettingEnabledForUser.put(userId, enabled);
Kevin Chyn1e043d472019-03-11 14:48:17 -0700389 updateFaceListeningState();
Kevin Chynb7b54a62018-09-28 18:48:12 -0700390 }
391 }
392 };
393
Fabian Kozynskiccde55d2019-06-26 10:06:09 -0400394 private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
395 @Override
396 public void onActiveDataSubscriptionIdChanged(int subId) {
397 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
398 }
399 };
400
Wink Savilled09c4ca2014-11-22 10:08:16 -0800401 private OnSubscriptionsChangedListener mSubscriptionListener =
402 new OnSubscriptionsChangedListener() {
Jim Miller52a61332014-11-12 19:29:51 -0800403 @Override
Wink Savilled09c4ca2014-11-22 10:08:16 -0800404 public void onSubscriptionsChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800405 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
406 }
407 };
408
Adrian Roos46842d92014-03-27 14:58:03 +0100409 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200410 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Jim Miller9f0753f2015-03-23 23:59:22 -0700411 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200412 private SparseBooleanArray mUserFaceAuthenticated = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200413 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100414
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700415 private static int sCurrentUser;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200416 private Runnable mUpdateBiometricListeningState = this::updateBiometricListeningState;
Adrian Roos30a2ae62018-04-25 19:09:50 +0200417 private static boolean sDisableHandlerCheckForTesting;
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700418
419 public synchronized static void setCurrentUser(int currentUser) {
420 sCurrentUser = currentUser;
421 }
422
423 public synchronized static int getCurrentUser() {
424 return sCurrentUser;
425 }
426
Adrian Roos46842d92014-03-27 14:58:03 +0100427 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700428 public void onTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200429 checkIsHandlerThread();
Adrian Roos46842d92014-03-27 14:58:03 +0100430 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200431 for (int i = 0; i < mCallbacks.size(); i++) {
432 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
433 if (cb != null) {
434 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700435 if (enabled && flags != 0) {
436 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200437 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200438 }
439 }
Adrian Roos46842d92014-03-27 14:58:03 +0100440 }
441
Lucas Dupinef886542018-01-03 16:03:07 -0800442 @Override
443 public void onTrustError(CharSequence message) {
444 dispatchErrorMessage(message);
445 }
446
Adrian Roos30a2ae62018-04-25 19:09:50 +0200447 private void handleSimSubscriptionInfoChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800448 if (DEBUG_SIM_STATES) {
449 Log.v(TAG, "onSubscriptionInfoChanged()");
Fabian Kozynskiccde55d2019-06-26 10:06:09 -0400450 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList(false);
Wink Savilled09c4ca2014-11-22 10:08:16 -0800451 if (sil != null) {
452 for (SubscriptionInfo subInfo : sil) {
453 Log.v(TAG, "SubInfo:" + subInfo);
454 }
455 } else {
456 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800457 }
458 }
459 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
460
461 // Hack level over 9000: Because the subscription id is not yet valid when we see the
462 // first update in handleSimStateChange, we need to force refresh all all SIM states
463 // so the subscription id for them is consistent.
Richard Choue0381b82018-04-24 03:48:59 +0000464 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
465 for (int i = 0; i < subscriptionInfos.size(); i++) {
466 SubscriptionInfo info = subscriptionInfos.get(i);
467 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
468 if (changed) {
469 changedSubscriptions.add(info);
470 }
471 }
472 for (int i = 0; i < changedSubscriptions.size(); i++) {
473 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800474 for (int j = 0; j < mCallbacks.size(); j++) {
475 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
476 if (cb != null) {
477 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
478 }
479 }
480 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500481 for (int j = 0; j < mCallbacks.size(); j++) {
482 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
483 if (cb != null) {
484 cb.onRefreshCarrierInfo();
485 }
486 }
Jim Miller52a61332014-11-12 19:29:51 -0800487 }
488
Jason Monk052082c2015-06-11 11:35:23 -0400489 private void handleAirplaneModeChanged() {
490 for (int j = 0; j < mCallbacks.size(); j++) {
491 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
492 if (cb != null) {
493 cb.onRefreshCarrierInfo();
494 }
495 }
496 }
497
Wink Savilled09c4ca2014-11-22 10:08:16 -0800498 /** @return List of SubscriptionInfo records, maybe empty but never null */
Adrian Roos316bf542016-08-23 17:53:07 +0200499 public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800500 List<SubscriptionInfo> sil = mSubscriptionInfo;
501 if (sil == null || forceReload) {
Fabian Kozynskiccde55d2019-06-26 10:06:09 -0400502 sil = mSubscriptionManager.getActiveSubscriptionInfoList(false);
Wink Savilled09c4ca2014-11-22 10:08:16 -0800503 }
504 if (sil == null) {
505 // getActiveSubscriptionInfoList was null callers expect an empty list.
506 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
507 } else {
508 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800509 }
510 return mSubscriptionInfo;
511 }
512
Adrian Roos7861c662014-07-25 15:37:28 +0200513 @Override
514 public void onTrustManagedChanged(boolean managed, int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200515 checkIsHandlerThread();
Adrian Roos7861c662014-07-25 15:37:28 +0200516 mUserTrustIsManaged.put(userId, managed);
517
518 for (int i = 0; i < mCallbacks.size(); i++) {
519 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
520 if (cb != null) {
521 cb.onTrustManagedChanged(userId);
522 }
523 }
524 }
525
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700526 /**
527 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is goingAway
528 * @param goingAway
529 */
530 public void setKeyguardGoingAway(boolean goingAway) {
531 mKeyguardGoingAway = goingAway;
Kevin Chyne22f1342017-09-26 10:03:38 -0700532 updateFingerprintListeningState();
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700533 }
534
Kevin Chyn2fefd462017-04-28 12:18:19 -0700535 /**
536 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is occluded
537 * @param occluded
538 */
539 public void setKeyguardOccluded(boolean occluded) {
540 mKeyguardOccluded = occluded;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200541 updateBiometricListeningState();
Kevin Chyn2fefd462017-04-28 12:18:19 -0700542 }
543
Kevin Chyn36778ff2017-09-07 19:55:38 -0700544 /**
Kevin Chyn6951d3d2019-06-10 14:07:13 -0700545 * Invoked when the secure camera is launched.
546 */
547 public void onCameraLaunched() {
548 mSecureCameraLaunched = true;
549 updateBiometricListeningState();
550 }
551
552 /**
Kevin Chyn36778ff2017-09-07 19:55:38 -0700553 * @return a cached version of DreamManager.isDreaming()
554 */
555 public boolean isDreaming() {
556 return mIsDreaming;
557 }
558
559 /**
560 * If the device is dreaming, awakens the device
561 */
562 public void awakenFromDream() {
563 if (mIsDreaming && mDreamManager != null) {
564 try {
565 mDreamManager.awaken();
566 } catch (RemoteException e) {
567 Log.e(TAG, "Unable to awaken from dream");
568 }
569 }
570 }
571
Lucas Dupin3d053532019-01-29 12:35:22 -0800572 @VisibleForTesting
573 protected void onFingerprintAuthenticated(int userId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700574 Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
Jim Miller9f0753f2015-03-23 23:59:22 -0700575 mUserFingerprintAuthenticated.put(userId, true);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700576 // Update/refresh trust state only if user can skip bouncer
577 if (getUserCanSkipBouncer(userId)) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200578 mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FINGERPRINT);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700579 }
Kevin Chyn625a0142017-04-10 14:53:59 -0700580 // Don't send cancel if authentication succeeds
581 mFingerprintCancelSignal = null;
Jim Millerf41fc962014-06-18 16:33:51 -0700582 for (int i = 0; i < mCallbacks.size(); i++) {
583 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
584 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200585 cb.onBiometricAuthenticated(userId, BiometricSourceType.FINGERPRINT);
Jim Millerf41fc962014-06-18 16:33:51 -0700586 }
587 }
Kevin Chyn2fefd462017-04-28 12:18:19 -0700588
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200589 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE),
590 BIOMETRIC_CONTINUE_DELAY_MS);
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700591
Kevin Chyn2fefd462017-04-28 12:18:19 -0700592 // Only authenticate fingerprint once when assistant is visible
593 mAssistantVisible = false;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700594
Nick Desaulniers1d396752016-07-25 15:05:33 -0700595 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700596 }
597
Jim Millerce7eb6d2015-04-03 19:29:13 -0700598 private void handleFingerprintAuthFailed() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700599 for (int i = 0; i < mCallbacks.size(); i++) {
600 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
601 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200602 cb.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700603 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700604 }
Lucas Dupin51996bb2019-05-16 17:56:43 -0700605 handleFingerprintHelp(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
606 mContext.getString(R.string.kg_fingerprint_not_recognized));
Jim Millerce7eb6d2015-04-03 19:29:13 -0700607 }
Jim Millerf41fc962014-06-18 16:33:51 -0700608
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700609 private void handleFingerprintAcquired(int acquireInfo) {
610 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
611 return;
612 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700613 for (int i = 0; i < mCallbacks.size(); i++) {
614 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
615 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200616 cb.onBiometricAcquired(BiometricSourceType.FINGERPRINT);
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700617 }
618 }
619 }
620
Jim Miller837fa7e2016-08-08 20:16:22 -0700621 private void handleFingerprintAuthenticated(int authUserId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700622 Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
Jim Millerf41fc962014-06-18 16:33:51 -0700623 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700624 final int userId;
625 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800626 userId = ActivityManager.getService().getCurrentUser().id;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700627 } catch (RemoteException e) {
628 Log.e(TAG, "Failed to get current user id: ", e);
629 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700630 }
Jim Miller837fa7e2016-08-08 20:16:22 -0700631 if (userId != authUserId) {
632 Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId);
633 return;
634 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700635 if (isFingerprintDisabled(userId)) {
636 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
637 return;
638 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700639 onFingerprintAuthenticated(userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700640 } finally {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200641 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Jim Millerf41fc962014-06-18 16:33:51 -0700642 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700643 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700644 }
645
Jim Miller9f0753f2015-03-23 23:59:22 -0700646 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700647 for (int i = 0; i < mCallbacks.size(); i++) {
648 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
649 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200650 cb.onBiometricHelp(msgId, helpString, BiometricSourceType.FINGERPRINT);
Jim Miller9f0753f2015-03-23 23:59:22 -0700651 }
652 }
653 }
654
Kevin Chyn0c45b072017-04-24 16:27:11 -0700655 private Runnable mRetryFingerprintAuthentication = new Runnable() {
656 @Override
657 public void run() {
658 Log.w(TAG, "Retrying fingerprint after HW unavailable, attempt " +
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200659 mHardwareFingerprintUnavailableRetryCount);
Kevin Chyn0c45b072017-04-24 16:27:11 -0700660 updateFingerprintListeningState();
661 }
662 };
663
Jim Miller9f0753f2015-03-23 23:59:22 -0700664 private void handleFingerprintError(int msgId, String errString) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700665 if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200666 && mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
667 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Kevin Chyn1123ba72018-10-26 10:34:06 -0700668 updateFingerprintListeningState();
Jorim Jaggi86bed402015-08-20 18:20:02 -0700669 } else {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200670 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Jorim Jaggi86bed402015-08-20 18:20:02 -0700671 }
Kevin Chyn0c45b072017-04-24 16:27:11 -0700672
673 if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) {
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700674 if (mHardwareFingerprintUnavailableRetryCount < HAL_ERROR_RETRY_MAX) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200675 mHardwareFingerprintUnavailableRetryCount++;
Kevin Chyn0c45b072017-04-24 16:27:11 -0700676 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700677 mHandler.postDelayed(mRetryFingerprintAuthentication, HAL_ERROR_RETRY_TIMEOUT);
Kevin Chyn0c45b072017-04-24 16:27:11 -0700678 }
679 }
680
Kevin Chyndf9d33e2017-05-03 21:40:12 -0700681 if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
Lucas Dupin8eec2682019-07-01 16:41:17 -0700682 mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
Kevin Chyndf9d33e2017-05-03 21:40:12 -0700683 getCurrentUser());
684 }
685
Jim Miller9f0753f2015-03-23 23:59:22 -0700686 for (int i = 0; i < mCallbacks.size(); i++) {
687 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
688 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200689 cb.onBiometricError(msgId, errString, BiometricSourceType.FINGERPRINT);
Jim Millerf41fc962014-06-18 16:33:51 -0700690 }
691 }
692 }
693
Jorim Jaggi3a464782015-08-28 16:59:13 -0700694 private void handleFingerprintLockoutReset() {
695 updateFingerprintListeningState();
696 }
697
Jorim Jaggi86bed402015-08-20 18:20:02 -0700698 private void setFingerprintRunningState(int fingerprintRunningState) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200699 boolean wasRunning = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
700 boolean isRunning = fingerprintRunningState == BIOMETRIC_STATE_RUNNING;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700701 mFingerprintRunningState = fingerprintRunningState;
Kevin Chynb4514d22019-04-15 13:47:25 -0700702 Log.d(TAG, "fingerprintRunningState: " + mFingerprintRunningState);
Jorim Jaggi86bed402015-08-20 18:20:02 -0700703 // Clients of KeyguardUpdateMonitor don't care about the internal state about the
Kevin Chynb4514d22019-04-15 13:47:25 -0700704 // asynchronousness of the cancel cycle. So only notify them if the actually running state
Jorim Jaggi86bed402015-08-20 18:20:02 -0700705 // has changed.
706 if (wasRunning != isRunning) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700707 notifyFingerprintRunningStateChanged();
708 }
709 }
710
711 private void notifyFingerprintRunningStateChanged() {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200712 checkIsHandlerThread();
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700713 for (int i = 0; i < mCallbacks.size(); i++) {
714 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
715 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200716 cb.onBiometricRunningStateChanged(isFingerprintDetectionRunning(),
717 BiometricSourceType.FINGERPRINT);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700718 }
719 }
720 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200721
Lucas Dupin3d053532019-01-29 12:35:22 -0800722 @VisibleForTesting
723 protected void onFaceAuthenticated(int userId) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200724 Trace.beginSection("KeyGuardUpdateMonitor#onFaceAuthenticated");
725 mUserFaceAuthenticated.put(userId, true);
726 // Update/refresh trust state only if user can skip bouncer
727 if (getUserCanSkipBouncer(userId)) {
728 mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FACE);
729 }
730 // Don't send cancel if authentication succeeds
731 mFaceCancelSignal = null;
732 for (int i = 0; i < mCallbacks.size(); i++) {
733 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
734 if (cb != null) {
735 cb.onBiometricAuthenticated(userId,
736 BiometricSourceType.FACE);
737 }
738 }
739
740 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE),
741 BIOMETRIC_CONTINUE_DELAY_MS);
742
743 // Only authenticate face once when assistant is visible
744 mAssistantVisible = false;
745
746 Trace.endSection();
747 }
748
749 private void handleFaceAuthFailed() {
Lucas Dupin38314812019-02-15 14:10:55 -0800750 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200751 for (int i = 0; i < mCallbacks.size(); i++) {
752 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
753 if (cb != null) {
754 cb.onBiometricAuthFailed(BiometricSourceType.FACE);
755 }
756 }
Lucas Dupin51996bb2019-05-16 17:56:43 -0700757 handleFaceHelp(BIOMETRIC_HELP_FACE_NOT_RECOGNIZED,
758 mContext.getString(R.string.kg_face_not_recognized));
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200759 }
760
761 private void handleFaceAcquired(int acquireInfo) {
762 if (acquireInfo != FaceManager.FACE_ACQUIRED_GOOD) {
763 return;
764 }
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700765 if (DEBUG_FACE) Log.d(TAG, "Face acquired");
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200766 for (int i = 0; i < mCallbacks.size(); i++) {
767 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
768 if (cb != null) {
769 cb.onBiometricAcquired(BiometricSourceType.FACE);
770 }
771 }
772 }
773
774 private void handleFaceAuthenticated(int authUserId) {
775 Trace.beginSection("KeyGuardUpdateMonitor#handlerFaceAuthenticated");
776 try {
Lucas Dupin9bae9c22019-06-04 16:37:40 -0700777 if (mGoingToSleep) {
778 Log.d(TAG, "Aborted successful auth because device is going to sleep.");
779 return;
780 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200781 final int userId;
782 try {
783 userId = ActivityManager.getService().getCurrentUser().id;
784 } catch (RemoteException e) {
785 Log.e(TAG, "Failed to get current user id: ", e);
786 return;
787 }
788 if (userId != authUserId) {
789 Log.d(TAG, "Face authenticated for wrong user: " + authUserId);
790 return;
791 }
792 if (isFaceDisabled(userId)) {
793 Log.d(TAG, "Face authentication disabled by DPM for userId: " + userId);
794 return;
795 }
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700796 if (DEBUG_FACE) Log.d(TAG, "Face auth succeeded for user " + userId);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200797 onFaceAuthenticated(userId);
798 } finally {
799 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
800 }
801 Trace.endSection();
802 }
803
804 private void handleFaceHelp(int msgId, String helpString) {
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700805 if (DEBUG_FACE) Log.d(TAG, "Face help received: " + helpString);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200806 for (int i = 0; i < mCallbacks.size(); i++) {
807 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
808 if (cb != null) {
809 cb.onBiometricHelp(msgId, helpString, BiometricSourceType.FACE);
810 }
811 }
812 }
813
814 private Runnable mRetryFaceAuthentication = new Runnable() {
815 @Override
816 public void run() {
817 Log.w(TAG, "Retrying face after HW unavailable, attempt " +
818 mHardwareFaceUnavailableRetryCount);
819 updateFaceListeningState();
820 }
821 };
822
823 private void handleFaceError(int msgId, String errString) {
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700824 if (DEBUG_FACE) Log.d(TAG, "Face error received: " + errString);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200825 if (msgId == FaceManager.FACE_ERROR_CANCELED
826 && mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
827 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
Kevin Chyn1123ba72018-10-26 10:34:06 -0700828 updateFaceListeningState();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200829 } else {
830 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
831 }
832
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700833 if (msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE
834 || msgId == FaceManager.FACE_ERROR_UNABLE_TO_PROCESS) {
835 if (mHardwareFaceUnavailableRetryCount < HAL_ERROR_RETRY_MAX) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200836 mHardwareFaceUnavailableRetryCount++;
837 mHandler.removeCallbacks(mRetryFaceAuthentication);
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700838 mHandler.postDelayed(mRetryFaceAuthentication, HAL_ERROR_RETRY_TIMEOUT);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200839 }
840 }
841
842 if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
Lucas Dupin8eec2682019-07-01 16:41:17 -0700843 mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200844 getCurrentUser());
845 }
846
Lucas Dupin51996bb2019-05-16 17:56:43 -0700847 // The face timeout message is not very actionable, let's ask the user to
848 // manually retry.
849 if (msgId == FaceManager.FACE_ERROR_TIMEOUT) {
850 errString = mContext.getString(R.string.keyguard_unlock);
851 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200852 for (int i = 0; i < mCallbacks.size(); i++) {
853 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
854 if (cb != null) {
855 cb.onBiometricError(msgId, errString,
856 BiometricSourceType.FACE);
857 }
858 }
859 }
860
861 private void handleFaceLockoutReset() {
862 updateFaceListeningState();
863 }
864
865 private void setFaceRunningState(int faceRunningState) {
866 boolean wasRunning = mFaceRunningState == BIOMETRIC_STATE_RUNNING;
867 boolean isRunning = faceRunningState == BIOMETRIC_STATE_RUNNING;
868 mFaceRunningState = faceRunningState;
Kevin Chynb4514d22019-04-15 13:47:25 -0700869 Log.d(TAG, "faceRunningState: " + mFaceRunningState);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200870 // Clients of KeyguardUpdateMonitor don't care about the internal state or about the
Kevin Chynb4514d22019-04-15 13:47:25 -0700871 // asynchronousness of the cancel cycle. So only notify them if the actually running state
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200872 // has changed.
873 if (wasRunning != isRunning) {
874 notifyFaceRunningStateChanged();
875 }
876 }
877
878 private void notifyFaceRunningStateChanged() {
879 for (int i = 0; i < mCallbacks.size(); i++) {
880 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
881 if (cb != null) {
882 cb.onBiometricRunningStateChanged(isFaceDetectionRunning(),
883 BiometricSourceType.FACE);
884 }
885 }
886 }
887
Adrian Roos4a410172014-08-20 17:41:44 +0200888 private void handleFaceUnlockStateChanged(boolean running, int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200889 checkIsHandlerThread();
Adrian Roos4a410172014-08-20 17:41:44 +0200890 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200891 for (int i = 0; i < mCallbacks.size(); i++) {
892 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
893 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200894 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200895 }
896 }
897 }
898
Adrian Roos4a410172014-08-20 17:41:44 +0200899 public boolean isFaceUnlockRunning(int userId) {
900 return mUserFaceUnlockRunning.get(userId);
901 }
902
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700903 public boolean isFingerprintDetectionRunning() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200904 return mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
905 }
906
907 public boolean isFaceDetectionRunning() {
908 return mFaceRunningState == BIOMETRIC_STATE_RUNNING;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700909 }
910
Jim Miller50e62182014-04-23 17:25:00 -0700911 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100912 // Don't allow trust agent if device is secured with a SIM PIN. This is here
913 // mainly because there's no other way to prompt the user to enter their SIM PIN
914 // once they get past the keyguard screen.
915 final boolean disabledBySimPin = isSimPinSecure();
916 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700917 }
918
Jim Miller06e34502014-07-17 14:46:05 -0700919 private boolean isFingerprintDisabled(int userId) {
920 final DevicePolicyManager dpm =
921 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
922 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
Adrian Roos733b6632015-08-21 14:32:35 -0700923 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0
924 || isSimPinSecure();
Jim Miller06e34502014-07-17 14:46:05 -0700925 }
926
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200927 private boolean isFaceDisabled(int userId) {
928 final DevicePolicyManager dpm =
929 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
930 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
931 & DevicePolicyManager.KEYGUARD_DISABLE_FACE) != 0
932 || isSimPinSecure();
933 }
934
935
Selim Cineke8bae622015-07-15 13:24:06 -0700936 public boolean getUserCanSkipBouncer(int userId) {
Steven Wucfe398d2019-03-21 11:32:15 -0400937 return getUserHasTrust(userId) || getUserUnlockedWithBiometric(userId);
Selim Cineke8bae622015-07-15 13:24:06 -0700938 }
939
Adrian Roos46842d92014-03-27 14:58:03 +0100940 public boolean getUserHasTrust(int userId) {
Selim Cineke8bae622015-07-15 13:24:06 -0700941 return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100942 }
943
Steven Wucfe398d2019-03-21 11:32:15 -0400944 /**
945 * Returns whether the user is unlocked with biometrics.
946 */
947 public boolean getUserUnlockedWithBiometric(int userId) {
948 boolean fingerprintOrFace = mUserFingerprintAuthenticated.get(userId)
949 || mUserFaceAuthenticated.get(userId);
950 return fingerprintOrFace && isUnlockingWithBiometricAllowed();
951 }
952
Adrian Roos7861c662014-07-25 15:37:28 +0200953 public boolean getUserTrustIsManaged(int userId) {
954 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
955 }
956
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200957 public boolean isUnlockingWithBiometricAllowed() {
958 return mStrongAuthTracker.isUnlockingWithBiometricAllowed();
Adrian Roosb5e47222015-08-14 15:53:06 -0700959 }
960
Lucas Dupin16013822018-05-17 18:00:16 -0700961 public boolean isUserInLockdown(int userId) {
Lucas Dupin8eec2682019-07-01 16:41:17 -0700962 return containsFlag(mStrongAuthTracker.getStrongAuthForUser(userId),
963 STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
Lucas Dupin16013822018-05-17 18:00:16 -0700964 }
965
Lucas Dupin7825b942019-06-03 20:22:39 -0700966 public boolean userNeedsStrongAuth() {
967 return mStrongAuthTracker.getStrongAuthForUser(getCurrentUser())
968 != LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
969 }
970
Lucas Dupin8eec2682019-07-01 16:41:17 -0700971 private boolean containsFlag(int haystack, int needle) {
972 return (haystack & needle) != 0;
973 }
974
Jorim Jaggi031f7952016-09-01 16:39:26 -0700975 public boolean needsSlowUnlockTransition() {
976 return mNeedsSlowUnlockTransition;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700977 }
978
Adrian Roosb5e47222015-08-14 15:53:06 -0700979 public StrongAuthTracker getStrongAuthTracker() {
980 return mStrongAuthTracker;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700981 }
982
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700983 private void notifyStrongAuthStateChanged(int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200984 checkIsHandlerThread();
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700985 for (int i = 0; i < mCallbacks.size(); i++) {
986 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
987 if (cb != null) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700988 cb.onStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700989 }
990 }
Selim Cinek1fcafc42015-07-20 14:39:25 -0700991 }
992
Adrian Roos91ba3072017-02-14 16:50:46 +0100993 public boolean isScreenOn() {
994 return mScreenOn;
995 }
996
Lucas Dupinef886542018-01-03 16:03:07 -0800997 private void dispatchErrorMessage(CharSequence message) {
998 for (int i = 0; i < mCallbacks.size(); i++) {
999 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1000 if (cb != null) {
1001 cb.onTrustAgentErrorMessage(message);
1002 }
1003 }
1004 }
1005
Lucas Dupin3d053532019-01-29 12:35:22 -08001006 @VisibleForTesting
1007 void setAssistantVisible(boolean assistantVisible) {
1008 mAssistantVisible = assistantVisible;
1009 updateBiometricListeningState();
1010 }
1011
Jim Miller8f09fd22013-03-14 19:04:28 -07001012 static class DisplayClientState {
1013 public int clientGeneration;
1014 public boolean clearing;
1015 public PendingIntent intent;
1016 public int playbackState;
1017 public long playbackEventTime;
1018 }
1019
1020 private DisplayClientState mDisplayClientState = new DisplayClientState();
1021
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001022 @VisibleForTesting
Lucas Dupin7ff82b02018-05-16 12:14:10 -07001023 protected final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001024
Jim Millerd72d5ac2015-09-29 18:55:32 -07001025 @Override
Jim Millerbbf1a742012-07-17 18:30:30 -07001026 public void onReceive(Context context, Intent intent) {
1027 final String action = intent.getAction();
1028 if (DEBUG) Log.d(TAG, "received broadcast " + action);
1029
1030 if (Intent.ACTION_TIME_TICK.equals(action)
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05001031 || Intent.ACTION_TIME_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -07001032 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05001033 } else if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
1034 final Message msg = mHandler.obtainMessage(
1035 MSG_TIMEZONE_UPDATE, intent.getStringExtra("time-zone"));
1036 mHandler.sendMessage(msg);
Jim Millerbbf1a742012-07-17 18:30:30 -07001037 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
1038 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
1039 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
1040 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
1041 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
Adrian Roos0c859ae2015-11-23 16:47:50 -08001042
1043 final int maxChargingMicroAmp = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
1044 int maxChargingMicroVolt = intent.getIntExtra(EXTRA_MAX_CHARGING_VOLTAGE, -1);
1045 final int maxChargingMicroWatt;
1046
1047 if (maxChargingMicroVolt <= 0) {
1048 maxChargingMicroVolt = DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT;
1049 }
1050 if (maxChargingMicroAmp > 0) {
1051 // Calculating muW = muA * muV / (10^6 mu^2 / mu); splitting up the divisor
1052 // to maintain precision equally on both factors.
1053 maxChargingMicroWatt = (maxChargingMicroAmp / 1000)
1054 * (maxChargingMicroVolt / 1000);
1055 } else {
1056 maxChargingMicroWatt = -1;
1057 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001058 final Message msg = mHandler.obtainMessage(
Adrian Roos7b043112015-07-10 13:00:33 -07001059 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
Adrian Roos0c859ae2015-11-23 16:47:50 -08001060 maxChargingMicroWatt));
Jim Millerbbf1a742012-07-17 18:30:30 -07001061 mHandler.sendMessage(msg);
1062 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Bill Linef81cbd2018-07-05 17:48:49 +08001063 SimData args = SimData.fromIntent(intent);
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001064 // ACTION_SIM_STATE_CHANGED is rebroadcast after unlocking the device to
1065 // keep compatibility with apps that aren't direct boot aware.
1066 // SysUI should just ignore this broadcast because it was already received
1067 // and processed previously.
1068 if (intent.getBooleanExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
Bill Linef81cbd2018-07-05 17:48:49 +08001069 // Guarantee mTelephonyCapable state after SysUI crash and restart
1070 if (args.simState == State.ABSENT) {
1071 mHandler.obtainMessage(MSG_TELEPHONY_CAPABLE, true).sendToTarget();
1072 }
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001073 return;
1074 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001075 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -08001076 Log.v(TAG, "action " + action
1077 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
1078 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -07001079 }
Jim Miller52a61332014-11-12 19:29:51 -08001080 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
1081 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -07001082 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
1083 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
1084 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
1085 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
1086 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
1087 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Jason Monk052082c2015-06-11 11:35:23 -04001088 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
1089 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001090 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -07001091 dispatchBootCompleted();
Etan Cohen47051d82015-07-06 16:19:04 -07001092 } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
1093 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
1094 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
1095 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
1096 if (DEBUG) {
1097 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
1098 + subId);
1099 }
Bonian Chena7e9e8c2019-06-02 23:59:31 +00001100 mHandler.sendMessage(
1101 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
Fabian Kozynskiccde55d2019-06-26 10:06:09 -04001102 } else if (TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED.equals(action)) {
1103 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
Alex Chauff7653d2018-02-01 17:18:08 +00001104 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
1105 action)) {
1106 mHandler.sendEmptyMessage(MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001107 }
1108 }
1109 };
Jim Miller2de5ee82012-06-14 22:22:50 -07001110
Lucas Dupin3d053532019-01-29 12:35:22 -08001111 @VisibleForTesting
1112 protected final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001113
Jim Millerd72d5ac2015-09-29 18:55:32 -07001114 @Override
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001115 public void onReceive(Context context, Intent intent) {
1116 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +02001117 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
1118 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
1119 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001120 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
1121 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +02001122 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001123 Trace.beginSection("KeyguardUpdateMonitor.mBroadcastAllReceiver#onReceive ACTION_FACE_UNLOCK_STARTED");
Adrian Roos48c796c2014-09-01 14:59:23 +02001124 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
1125 getSendingUserId()));
Nick Desaulniers1d396752016-07-25 15:05:33 -07001126 Trace.endSection();
Adrian Roos48c796c2014-09-01 14:59:23 +02001127 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
1128 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
1129 getSendingUserId()));
1130 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
1131 .equals(action)) {
1132 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001133 } else if (ACTION_USER_UNLOCKED.equals(action)) {
1134 mHandler.sendEmptyMessage(MSG_USER_UNLOCKED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001135 }
1136 }
1137 };
Jim Miller9f0753f2015-03-23 23:59:22 -07001138
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001139 private final FingerprintManager.LockoutResetCallback mFingerprintLockoutResetCallback
Jorim Jaggi3a464782015-08-28 16:59:13 -07001140 = new FingerprintManager.LockoutResetCallback() {
1141 @Override
1142 public void onLockoutReset() {
1143 handleFingerprintLockoutReset();
1144 }
1145 };
1146
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001147 private final FaceManager.LockoutResetCallback mFaceLockoutResetCallback
1148 = new FaceManager.LockoutResetCallback() {
1149 @Override
1150 public void onLockoutReset() {
1151 handleFaceLockoutReset();
1152 }
1153 };
1154
1155 private FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback
Jim Miller9f0753f2015-03-23 23:59:22 -07001156 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -07001157
1158 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -07001159 public void onAuthenticationFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001160 handleFingerprintAuthFailed();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001161 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001162
1163 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -07001164 public void onAuthenticationSucceeded(AuthenticationResult result) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001165 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
Jim Miller837fa7e2016-08-08 20:16:22 -07001166 handleFingerprintAuthenticated(result.getUserId());
Nick Desaulniers1d396752016-07-25 15:05:33 -07001167 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -07001168 }
1169
1170 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -07001171 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001172 handleFingerprintHelp(helpMsgId, helpString.toString());
Jim Miller9f0753f2015-03-23 23:59:22 -07001173 }
1174
1175 @Override
1176 public void onAuthenticationError(int errMsgId, CharSequence errString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001177 handleFingerprintError(errMsgId, errString.toString());
1178 }
1179
1180 @Override
1181 public void onAuthenticationAcquired(int acquireInfo) {
1182 handleFingerprintAcquired(acquireInfo);
Jim Millerf41fc962014-06-18 16:33:51 -07001183 }
1184 };
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001185
Lucas Dupin3d053532019-01-29 12:35:22 -08001186 @VisibleForTesting
1187 FaceManager.AuthenticationCallback mFaceAuthenticationCallback
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001188 = new FaceManager.AuthenticationCallback() {
1189
1190 @Override
1191 public void onAuthenticationFailed() {
1192 handleFaceAuthFailed();
1193 }
1194
1195 @Override
1196 public void onAuthenticationSucceeded(FaceManager.AuthenticationResult result) {
1197 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
1198 handleFaceAuthenticated(result.getUserId());
1199 Trace.endSection();
1200 }
1201
1202 @Override
1203 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
1204 handleFaceHelp(helpMsgId, helpString.toString());
1205 }
1206
1207 @Override
1208 public void onAuthenticationError(int errMsgId, CharSequence errString) {
1209 handleFaceError(errMsgId, errString.toString());
1210 }
1211
1212 @Override
1213 public void onAuthenticationAcquired(int acquireInfo) {
1214 handleFaceAcquired(acquireInfo);
1215 }
1216 };
1217
Jim Miller9f0753f2015-03-23 23:59:22 -07001218 private CancellationSignal mFingerprintCancelSignal;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001219 private CancellationSignal mFaceCancelSignal;
Jim Miller9f0753f2015-03-23 23:59:22 -07001220 private FingerprintManager mFpm;
Kevin Chynb7b54a62018-09-28 18:48:12 -07001221 private FaceManager mFaceManager;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001222
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001223 /**
Jim Miller47088bb2009-11-24 00:40:16 -08001224 * When we receive a
1225 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -07001226 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001227 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -08001228 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001229 */
Jim Miller52a61332014-11-12 19:29:51 -08001230 private static class SimData {
1231 public State simState;
1232 public int slotId;
1233 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001234
Jim Miller52a61332014-11-12 19:29:51 -08001235 SimData(State state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -08001236 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -08001237 slotId = slot;
1238 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -08001239 }
1240
Jim Miller52a61332014-11-12 19:29:51 -08001241 static SimData fromIntent(Intent intent) {
1242 State state;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001243 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
1244 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
1245 }
Wink Savillea639b312012-07-10 12:37:54 -07001246 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
Jayachandran Cbd481352019-05-21 16:02:23 -07001247 int slotId = intent.getIntExtra(PhoneConstants.PHONE_KEY, 0);
Jim Miller52a61332014-11-12 19:29:51 -08001248 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
Wink Savilled09c4ca2014-11-22 10:08:16 -08001249 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea639b312012-07-10 12:37:54 -07001250 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -07001251 final String absentReason = intent
Wink Savillea639b312012-07-10 12:37:54 -07001252 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -07001253
Wink Savillea639b312012-07-10 12:37:54 -07001254 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -07001255 absentReason)) {
Wink Savillea639b312012-07-10 12:37:54 -07001256 state = IccCardConstants.State.PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -07001257 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001258 state = IccCardConstants.State.ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -07001259 }
Wink Savillea639b312012-07-10 12:37:54 -07001260 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
1261 state = IccCardConstants.State.READY;
1262 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001263 final String lockedReason = intent
Wink Savillea639b312012-07-10 12:37:54 -07001264 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
1265 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
1266 state = IccCardConstants.State.PIN_REQUIRED;
1267 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
1268 state = IccCardConstants.State.PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001269 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001270 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001271 }
Wink Savillea639b312012-07-10 12:37:54 -07001272 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
1273 state = IccCardConstants.State.NETWORK_LOCKED;
Wileen Chiu6b8b22e2014-10-29 22:48:21 +05301274 } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
1275 state = IccCardConstants.State.CARD_IO_ERROR;
Jim Miller109f1fd2012-09-19 20:44:16 -07001276 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
1277 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
1278 // This is required because telephony doesn't return to "READY" after
1279 // these state transitions. See bug 7197471.
1280 state = IccCardConstants.State.READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001281 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001282 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001283 }
Jim Miller52a61332014-11-12 19:29:51 -08001284 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001285 }
1286
Jim Millerd72d5ac2015-09-29 18:55:32 -07001287 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001288 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -08001289 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001290 }
1291 }
1292
Adrian Roos12c1ef52014-06-04 13:54:08 +02001293 public static class BatteryStatus {
Adrian Roos7b043112015-07-10 13:00:33 -07001294 public static final int CHARGING_UNKNOWN = -1;
1295 public static final int CHARGING_SLOWLY = 0;
1296 public static final int CHARGING_REGULAR = 1;
1297 public static final int CHARGING_FAST = 2;
1298
Jim Miller16464b82011-10-20 21:10:13 -07001299 public final int status;
1300 public final int level;
1301 public final int plugged;
1302 public final int health;
Adrian Roos0c859ae2015-11-23 16:47:50 -08001303 public final int maxChargingWattage;
1304 public BatteryStatus(int status, int level, int plugged, int health,
1305 int maxChargingWattage) {
Jim Miller16464b82011-10-20 21:10:13 -07001306 this.status = status;
1307 this.level = level;
1308 this.plugged = plugged;
1309 this.health = health;
Adrian Roos0c859ae2015-11-23 16:47:50 -08001310 this.maxChargingWattage = maxChargingWattage;
Jim Miller16464b82011-10-20 21:10:13 -07001311 }
1312
Jim Millerbbf1a742012-07-17 18:30:30 -07001313 /**
Brian Muramatsua92a01b2012-09-05 21:54:39 -07001314 * Determine whether the device is plugged in (USB, power, or wireless).
Jim Millerbbf1a742012-07-17 18:30:30 -07001315 * @return true if the device is plugged in.
1316 */
Adrian Roosad3bc7f2014-10-30 18:29:38 +01001317 public boolean isPluggedIn() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001318 return plugged == BatteryManager.BATTERY_PLUGGED_AC
Brian Muramatsua92a01b2012-09-05 21:54:39 -07001319 || plugged == BatteryManager.BATTERY_PLUGGED_USB
1320 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Jim Millerbbf1a742012-07-17 18:30:30 -07001321 }
1322
1323 /**
Beverly2034c832018-03-19 11:18:51 -04001324 * Determine whether the device is plugged in (USB, power).
1325 * @return true if the device is plugged in wired (as opposed to wireless)
1326 */
1327 public boolean isPluggedInWired() {
1328 return plugged == BatteryManager.BATTERY_PLUGGED_AC
1329 || plugged == BatteryManager.BATTERY_PLUGGED_USB;
1330 }
1331
1332 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001333 * Whether or not the device is charged. Note that some devices never return 100% for
1334 * battery level, so this allows either battery level or status to determine if the
1335 * battery is charged.
1336 * @return true if the device is charged
1337 */
1338 public boolean isCharged() {
1339 return status == BATTERY_STATUS_FULL || level >= 100;
1340 }
1341
1342 /**
1343 * Whether battery is low and needs to be charged.
1344 * @return true if battery is low
1345 */
1346 public boolean isBatteryLow() {
1347 return level < LOW_BATTERY_THRESHOLD;
1348 }
1349
Adrian Roos7b043112015-07-10 13:00:33 -07001350 public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
Adrian Roos0c859ae2015-11-23 16:47:50 -08001351 return maxChargingWattage <= 0 ? CHARGING_UNKNOWN :
1352 maxChargingWattage < slowThreshold ? CHARGING_SLOWLY :
1353 maxChargingWattage > fastThreshold ? CHARGING_FAST :
Adrian Roos7b043112015-07-10 13:00:33 -07001354 CHARGING_REGULAR;
1355 }
Lucas Dupin3fcdd472018-01-19 19:06:45 -08001356
1357 @Override
1358 public String toString() {
1359 return "BatteryStatus{status=" + status + ",level=" + level + ",plugged=" + plugged
1360 + ",health=" + health + ",maxChargingWattage=" + maxChargingWattage + "}";
1361 }
Jim Miller16464b82011-10-20 21:10:13 -07001362 }
1363
Lucas Dupin3d053532019-01-29 12:35:22 -08001364 public static class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
1365 private final Consumer<Integer> mStrongAuthRequiredChangedCallback;
1366
1367 public StrongAuthTracker(Context context,
1368 Consumer<Integer> strongAuthRequiredChangedCallback) {
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001369 super(context);
Lucas Dupin3d053532019-01-29 12:35:22 -08001370 mStrongAuthRequiredChangedCallback = strongAuthRequiredChangedCallback;
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001371 }
Adrian Roosb5e47222015-08-14 15:53:06 -07001372
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001373 public boolean isUnlockingWithBiometricAllowed() {
Adrian Roosb5e47222015-08-14 15:53:06 -07001374 int userId = getCurrentUser();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001375 return isBiometricAllowedForUser(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -07001376 }
1377
1378 public boolean hasUserAuthenticatedSinceBoot() {
1379 int userId = getCurrentUser();
1380 return (getStrongAuthForUser(userId)
1381 & STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
1382 }
1383
1384 @Override
1385 public void onStrongAuthRequiredChanged(int userId) {
Lucas Dupin3d053532019-01-29 12:35:22 -08001386 mStrongAuthRequiredChangedCallback.accept(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -07001387 }
1388 }
1389
Jim Millerdcb3d842012-08-23 19:18:12 -07001390 public static KeyguardUpdateMonitor getInstance(Context context) {
1391 if (sInstance == null) {
1392 sInstance = new KeyguardUpdateMonitor(context);
1393 }
1394 return sInstance;
1395 }
1396
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001397 protected void handleStartedWakingUp() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001398 Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001399 updateBiometricListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001400 final int count = mCallbacks.size();
1401 for (int i = 0; i < count; i++) {
1402 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1403 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001404 cb.onStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -07001405 }
1406 }
Nick Desaulniers1d396752016-07-25 15:05:33 -07001407 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -07001408 }
1409
Jorim Jaggi95e40382015-09-16 15:53:42 -07001410 protected void handleStartedGoingToSleep(int arg1) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001411 clearBiometricRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -07001412 final int count = mCallbacks.size();
1413 for (int i = 0; i < count; i++) {
1414 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1415 if (cb != null) {
Jorim Jaggi95e40382015-09-16 15:53:42 -07001416 cb.onStartedGoingToSleep(arg1);
1417 }
1418 }
1419 mGoingToSleep = true;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001420 updateBiometricListeningState();
Jorim Jaggi95e40382015-09-16 15:53:42 -07001421 }
1422
1423 protected void handleFinishedGoingToSleep(int arg1) {
1424 mGoingToSleep = false;
1425 final int count = mCallbacks.size();
1426 for (int i = 0; i < count; i++) {
1427 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1428 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001429 cb.onFinishedGoingToSleep(arg1);
Jim Miller20daffd2013-10-07 14:59:53 -07001430 }
1431 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001432 updateBiometricListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001433 }
1434
Jorim Jaggif1518da2015-07-30 11:56:36 -07001435 private void handleScreenTurnedOn() {
1436 final int count = mCallbacks.size();
1437 for (int i = 0; i < count; i++) {
1438 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1439 if (cb != null) {
1440 cb.onScreenTurnedOn();
1441 }
1442 }
1443 }
1444
1445 private void handleScreenTurnedOff() {
Lucas Dupinca88e5f2019-05-14 16:11:08 -07001446 mLockIconPressed = false;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001447 mHardwareFingerprintUnavailableRetryCount = 0;
1448 mHardwareFaceUnavailableRetryCount = 0;
Jorim Jaggif1518da2015-07-30 11:56:36 -07001449 final int count = mCallbacks.size();
1450 for (int i = 0; i < count; i++) {
1451 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1452 if (cb != null) {
1453 cb.onScreenTurnedOff();
1454 }
1455 }
1456 }
1457
Selim Cinek99415392016-09-09 14:58:41 -07001458 private void handleDreamingStateChanged(int dreamStart) {
1459 final int count = mCallbacks.size();
Kevin Chyn36778ff2017-09-07 19:55:38 -07001460 mIsDreaming = dreamStart == 1;
Selim Cinek99415392016-09-09 14:58:41 -07001461 for (int i = 0; i < count; i++) {
1462 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1463 if (cb != null) {
Kevin Chyn36778ff2017-09-07 19:55:38 -07001464 cb.onDreamingStateChanged(mIsDreaming);
Selim Cinek99415392016-09-09 14:58:41 -07001465 }
1466 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001467 updateBiometricListeningState();
Selim Cinek99415392016-09-09 14:58:41 -07001468 }
1469
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001470 private void handleUserInfoChanged(int userId) {
1471 for (int i = 0; i < mCallbacks.size(); i++) {
1472 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1473 if (cb != null) {
1474 cb.onUserInfoChanged(userId);
1475 }
1476 }
1477 }
1478
Jorim Jaggidadafd42016-09-30 07:20:25 -07001479 private void handleUserUnlocked() {
1480 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1481 for (int i = 0; i < mCallbacks.size(); i++) {
1482 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1483 if (cb != null) {
1484 cb.onUserUnlocked();
1485 }
1486 }
1487 }
1488
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001489 @VisibleForTesting
1490 protected KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001491 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -08001492 mSubscriptionManager = SubscriptionManager.from(context);
Michael Jurkafff56142012-11-28 16:51:00 -08001493 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Lucas Dupin3d053532019-01-29 12:35:22 -08001494 mStrongAuthTracker = new StrongAuthTracker(context, this::notifyStrongAuthStateChanged);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001495
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001496 // Since device can't be un-provisioned, we only need to register a content observer
1497 // to update mDeviceProvisioned when we are...
1498 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001499 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001500 }
Jim Miller47088bb2009-11-24 00:40:16 -08001501
Jim Millerbbf1a742012-07-17 18:30:30 -07001502 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Adrian Roos7b043112015-07-10 13:00:33 -07001503 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001504
Jim Millerbbf1a742012-07-17 18:30:30 -07001505 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001506 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001507 filter.addAction(Intent.ACTION_TIME_TICK);
1508 filter.addAction(Intent.ACTION_TIME_CHANGED);
1509 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
1510 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Jason Monk052082c2015-06-11 11:35:23 -04001511 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001512 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Etan Cohen47051d82015-07-06 16:19:04 -07001513 filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Fabian Kozynskiccde55d2019-06-26 10:06:09 -04001514 filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -08001515 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -08001516 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Alex Chauff7653d2018-02-01 17:18:08 +00001517 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jason Monk7bb59302018-05-10 19:38:18 -07001518 context.registerReceiver(mBroadcastReceiver, filter, null, mHandler);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001519
Adam Cohenc276e822012-11-08 13:01:08 -08001520 final IntentFilter bootCompleteFilter = new IntentFilter();
1521 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1522 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
Jason Monk7bb59302018-05-10 19:38:18 -07001523 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter, null, mHandler);
Adam Cohenc276e822012-11-08 13:01:08 -08001524
Adrian Roos48c796c2014-09-01 14:59:23 +02001525 final IntentFilter allUserFilter = new IntentFilter();
1526 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
1527 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
1528 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
1529 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
1530 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001531 allUserFilter.addAction(ACTION_USER_UNLOCKED);
Adrian Roos48c796c2014-09-01 14:59:23 +02001532 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Jason Monk7bb59302018-05-10 19:38:18 -07001533 null, mHandler);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001534
Wink Saville071743f2015-01-12 17:11:04 -08001535 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001536 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001537 ActivityManager.getService().registerUserSwitchObserver(
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001538 new UserSwitchObserver() {
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001539 @Override
1540 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001541 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001542 newUserId, 0, reply));
1543 }
1544 @Override
1545 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001546 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +02001547 newUserId, 0));
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001548 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001549 }, TAG);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001550 } catch (RemoteException e) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001551 e.rethrowAsRuntimeException();
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001552 }
Adrian Roos46842d92014-03-27 14:58:03 +01001553
Jorim Jaggi237b0612015-05-01 14:28:49 -07001554 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
1555 mTrustManager.registerTrustListener(this);
Michal Karpinskic52f8672016-11-18 11:32:45 +00001556 mLockPatternUtils = new LockPatternUtils(context);
1557 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Jim Millerf41fc962014-06-18 16:33:51 -07001558
Kevin Chyn36778ff2017-09-07 19:55:38 -07001559 mDreamManager = IDreamManager.Stub.asInterface(
1560 ServiceManager.getService(DreamService.DREAM_SERVICE));
1561
Jorim Jaggi3f124262016-11-22 13:45:17 +01001562 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
1563 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
1564 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001565 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
Kevin Chynb7b54a62018-09-28 18:48:12 -07001566 mFaceManager = (FaceManager) context.getSystemService(Context.FACE_SERVICE);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001567 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07001568
1569 if (mFpm != null || mFaceManager != null) {
1570 mBiometricManager = context.getSystemService(BiometricManager.class);
1571 mBiometricManager.registerEnabledOnKeyguardCallback(mBiometricEnabledCallback);
1572 }
1573
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001574 updateBiometricListeningState();
Jorim Jaggi3a464782015-08-28 16:59:13 -07001575 if (mFpm != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001576 mFpm.addLockoutResetCallback(mFingerprintLockoutResetCallback);
1577 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07001578 if (mFaceManager != null) {
1579 mFaceManager.addLockoutResetCallback(mFaceLockoutResetCallback);
Jorim Jaggi3a464782015-08-28 16:59:13 -07001580 }
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001581
Winson Chung2cf6ad82017-11-09 17:36:59 -08001582 ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001583 mUserManager = context.getSystemService(UserManager.class);
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001584 mIsPrimaryUser = mUserManager.isPrimaryUser();
Alex Chauff7653d2018-02-01 17:18:08 +00001585 mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
1586 mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
Bill Linef81cbd2018-07-05 17:48:49 +08001587 updateAirplaneModeState();
Fabian Kozynskiccde55d2019-06-26 10:06:09 -04001588
1589 TelephonyManager telephony =
1590 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
1591 if (telephony != null) {
1592 telephony.listen(mPhoneStateListener, LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
1593 }
Bill Linef81cbd2018-07-05 17:48:49 +08001594 }
1595
1596 private void updateAirplaneModeState() {
1597 // ACTION_AIRPLANE_MODE_CHANGED do not broadcast if device set AirplaneMode ON and boot
1598 if (!WirelessUtils.isAirplaneModeOn(mContext)
1599 || mHandler.hasMessages(MSG_AIRPLANE_MODE_CHANGED)) {
1600 return;
1601 }
1602 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Jorim Jaggiea657062015-04-28 13:45:11 -07001603 }
1604
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001605 private void updateBiometricListeningState() {
1606 updateFingerprintListeningState();
1607 updateFaceListeningState();
1608 }
1609
Jorim Jaggiea657062015-04-28 13:45:11 -07001610 private void updateFingerprintListeningState() {
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001611 // If this message exists, we should not authenticate again until this message is
1612 // consumed by the handler
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001613 if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001614 return;
1615 }
Kevin Chyn0c45b072017-04-24 16:27:11 -07001616 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
Jorim Jaggiea657062015-04-28 13:45:11 -07001617 boolean shouldListenForFingerprint = shouldListenForFingerprint();
Adrian Roos2aaf9442018-11-20 16:57:33 +01001618 boolean runningOrRestarting = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING
1619 || mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING;
1620 if (runningOrRestarting && !shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001621 stopListeningForFingerprint();
Adrian Roos2aaf9442018-11-20 16:57:33 +01001622 } else if (!runningOrRestarting && shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001623 startListeningForFingerprint();
1624 }
1625 }
1626
Lucas Dupin3d053532019-01-29 12:35:22 -08001627 /**
Lucas Dupine0516d52019-02-05 17:54:06 -05001628 * Called whenever passive authentication is requested or aborted by a sensor.
1629 * @param active If the interrupt started or ended.
Lucas Dupin3d053532019-01-29 12:35:22 -08001630 */
Lucas Dupine0516d52019-02-05 17:54:06 -05001631 public void onAuthInterruptDetected(boolean active) {
1632 if (DEBUG) Log.d(TAG, "onAuthInterruptDetected(" + active + ")");
1633 if (mAuthInterruptActive == active) {
1634 return;
1635 }
1636 mAuthInterruptActive = active;
Lucas Dupin3d053532019-01-29 12:35:22 -08001637 updateFaceListeningState();
1638 }
1639
Lucas Dupin8f3faac2019-03-12 15:28:49 -07001640 /**
1641 * Requests face authentication if we're on a state where it's allowed.
1642 * This will re-trigger auth in case it fails.
1643 */
1644 public void requestFaceAuth() {
1645 if (DEBUG) Log.d(TAG, "requestFaceAuth()");
1646 updateFaceListeningState();
1647 }
1648
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001649 private void updateFaceListeningState() {
1650 // If this message exists, we should not authenticate again until this message is
1651 // consumed by the handler
1652 if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
1653 return;
1654 }
1655 mHandler.removeCallbacks(mRetryFaceAuthentication);
1656 boolean shouldListenForFace = shouldListenForFace();
1657 if (mFaceRunningState == BIOMETRIC_STATE_RUNNING && !shouldListenForFace) {
1658 stopListeningForFace();
1659 } else if (mFaceRunningState != BIOMETRIC_STATE_RUNNING
1660 && shouldListenForFace) {
1661 startListeningForFace();
1662 }
1663 }
1664
Kevin Chyn129f60f2017-08-11 17:24:42 -07001665 private boolean shouldListenForFingerprintAssistant() {
1666 return mAssistantVisible && mKeyguardOccluded
1667 && !mUserFingerprintAuthenticated.get(getCurrentUser(), false)
1668 && !mUserHasTrust.get(getCurrentUser(), false);
1669 }
1670
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001671 private boolean shouldListenForFaceAssistant() {
1672 return mAssistantVisible && mKeyguardOccluded
1673 && !mUserFaceAuthenticated.get(getCurrentUser(), false)
1674 && !mUserHasTrust.get(getCurrentUser(), false);
1675 }
1676
Jorim Jaggiea657062015-04-28 13:45:11 -07001677 private boolean shouldListenForFingerprint() {
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001678 // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
1679 // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
1680 final boolean shouldListen = (mKeyguardIsVisible || !mDeviceInteractive ||
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001681 (mBouncer && !mKeyguardGoingAway) || mGoingToSleep ||
Kevin Chyn36778ff2017-09-07 19:55:38 -07001682 shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming))
Lucas Dupinc12fad32019-05-14 20:59:17 +00001683 && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser())
Kevin Chyn225eea72019-03-06 16:42:00 -08001684 && (!mKeyguardGoingAway || !mDeviceInteractive) && mIsPrimaryUser;
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001685 return shouldListen;
Jim Miller9f0753f2015-03-23 23:59:22 -07001686 }
1687
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001688 private boolean shouldListenForFace() {
Lucas Dupin3d053532019-01-29 12:35:22 -08001689 final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep;
1690 final int user = getCurrentUser();
Robert Snoeberger5dcdf352019-06-24 11:28:28 -04001691 final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user);
1692 final boolean isLockOutOrLockDown =
Lucas Dupin8eec2682019-07-01 16:41:17 -07001693 containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_LOCKOUT)
1694 || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
1695 || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
1696 final boolean isEncryptedOrTimedOut =
1697 containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT)
1698 || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
Lucas Dupin9e484aa2019-06-24 13:38:00 -07001699
Lucas Dupin4befb742019-07-01 11:31:31 -07001700 boolean canBypass = mKeyguardBypassController != null
1701 && mKeyguardBypassController.canBypass();
Lucas Dupin9e484aa2019-06-24 13:38:00 -07001702 // There's no reason to ask the HAL for authentication when the user can dismiss the
1703 // bouncer, unless we're bypassing and need to auto-dismiss the lock screen even when
1704 // TrustAgents or biometrics are keeping the device unlocked.
Lucas Dupin4befb742019-07-01 11:31:31 -07001705 boolean becauseCannotSkipBouncer = !getUserCanSkipBouncer(user) || canBypass;
Lucas Dupin9e484aa2019-06-24 13:38:00 -07001706
Lucas Dupin8eec2682019-07-01 16:41:17 -07001707 // Scan even when encrypted or timeout to show a preemptive bouncer when bypassing.
1708 // Lockout/lockdown modes shouldn't scan, since they are more explicit.
1709 boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass && !mBouncer)
1710 && !isLockOutOrLockDown;
1711
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001712 // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
1713 // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
Lucas Dupine0516d52019-02-05 17:54:06 -05001714 return (mBouncer || mAuthInterruptActive || awakeKeyguard || shouldListenForFaceAssistant())
Lucas Dupin9e484aa2019-06-24 13:38:00 -07001715 && !mSwitchingUser && !isFaceDisabled(user) && becauseCannotSkipBouncer
Lucas Dupin7d95f152019-07-17 16:25:54 -07001716 && !mKeyguardGoingAway && mFaceSettingEnabledForUser.get(user) && !mLockIconPressed
Lucas Dupin8eec2682019-07-01 16:41:17 -07001717 && strongAuthAllowsScanning && mIsPrimaryUser
1718 && !mSecureCameraLaunched;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001719 }
1720
Lucas Dupinca88e5f2019-05-14 16:11:08 -07001721 /**
1722 * Whenever the lock icon is long pressed, disabling trust agents.
1723 * This means that we cannot auth passively (face) until the user presses power.
1724 */
1725 public void onLockIconPressed() {
1726 mLockIconPressed = true;
1727 mUserFaceAuthenticated.put(getCurrentUser(), false);
1728 updateFaceListeningState();
1729 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001730
Jim Millerce7eb6d2015-04-03 19:29:13 -07001731 private void startListeningForFingerprint() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001732 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING) {
1733 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001734 return;
1735 }
Adrian Roos2aaf9442018-11-20 16:57:33 +01001736 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1737 // Waiting for restart via handleFingerprintError().
1738 return;
1739 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001740 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Lucas Dupin8f3faac2019-03-12 15:28:49 -07001741 int userId = getCurrentUser();
Jorim Jaggi71448a72015-08-18 19:49:04 -07001742 if (isUnlockWithFingerprintPossible(userId)) {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001743 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001744 mFingerprintCancelSignal.cancel();
1745 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001746 mFingerprintCancelSignal = new CancellationSignal();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001747 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mFingerprintAuthenticationCallback,
1748 null, userId);
1749 setFingerprintRunningState(BIOMETRIC_STATE_RUNNING);
1750 }
1751 }
1752
1753 private void startListeningForFace() {
1754 if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING) {
1755 setFaceRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);
1756 return;
1757 }
1758 if (DEBUG) Log.v(TAG, "startListeningForFace()");
Lucas Dupin8f3faac2019-03-12 15:28:49 -07001759 int userId = getCurrentUser();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001760 if (isUnlockWithFacePossible(userId)) {
1761 if (mFaceCancelSignal != null) {
1762 mFaceCancelSignal.cancel();
1763 }
1764 mFaceCancelSignal = new CancellationSignal();
Kevin Chynb7b54a62018-09-28 18:48:12 -07001765 mFaceManager.authenticate(null, mFaceCancelSignal, 0,
Kevin Chyn8d2694a2019-04-11 18:30:40 -07001766 mFaceAuthenticationCallback, null, userId);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001767 setFaceRunningState(BIOMETRIC_STATE_RUNNING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001768 }
1769 }
1770
Lucas Dupin8d48fc42019-04-25 14:34:12 -07001771 /**
1772 * If biometrics hardware is available, not disabled, and user has enrolled templates.
1773 * This does NOT check if the device is encrypted or in lockdown.
1774 *
1775 * @param userId User that's trying to unlock.
1776 * @return {@code true} if possible.
1777 */
1778 public boolean isUnlockingWithBiometricsPossible(int userId) {
1779 return isUnlockWithFacePossible(userId) || isUnlockWithFingerprintPossible(userId);
1780 }
1781
1782 private boolean isUnlockWithFingerprintPossible(int userId) {
Selim Cinek3122fa82015-06-18 01:38:59 -07001783 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
1784 && mFpm.getEnrolledFingerprints(userId).size() > 0;
1785 }
1786
Lucas Dupin4c507042019-07-22 16:47:34 -07001787 private boolean isUnlockWithFacePossible(int userId) {
1788 return isFaceAuthEnabledForUser(userId) && !isFaceDisabled(userId);
1789 }
1790
Lucas Dupin7156bc72019-05-03 19:37:39 -07001791 /**
Lucas Dupin7d95f152019-07-17 16:25:54 -07001792 * If face hardware is available, user has enrolled and enabled auth via setting.
Lucas Dupin7156bc72019-05-03 19:37:39 -07001793 */
Lucas Dupin4c507042019-07-22 16:47:34 -07001794 public boolean isFaceAuthEnabledForUser(int userId) {
Kevin Chynb7b54a62018-09-28 18:48:12 -07001795 return mFaceManager != null && mFaceManager.isHardwareDetected()
Lucas Dupin7d95f152019-07-17 16:25:54 -07001796 && mFaceManager.hasEnrolledTemplates(userId)
1797 && mFaceSettingEnabledForUser.get(userId);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001798 }
1799
Jorim Jaggiea657062015-04-28 13:45:11 -07001800 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001801 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001802 if (mFingerprintRunningState == BIOMETRIC_STATE_RUNNING) {
Kevin Chyn2fefd462017-04-28 12:18:19 -07001803 if (mFingerprintCancelSignal != null) {
1804 mFingerprintCancelSignal.cancel();
1805 mFingerprintCancelSignal = null;
1806 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001807 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001808 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001809 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1810 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING);
1811 }
1812 }
1813
1814 private void stopListeningForFace() {
1815 if (DEBUG) Log.v(TAG, "stopListeningForFace()");
1816 if (mFaceRunningState == BIOMETRIC_STATE_RUNNING) {
1817 if (mFaceCancelSignal != null) {
1818 mFaceCancelSignal.cancel();
1819 mFaceCancelSignal = null;
1820 }
1821 setFaceRunningState(BIOMETRIC_STATE_CANCELLING);
1822 }
1823 if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1824 setFaceRunningState(BIOMETRIC_STATE_CANCELLING);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001825 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001826 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001827
Michael Jurkafff56142012-11-28 16:51:00 -08001828 private boolean isDeviceProvisionedInSettingsDb() {
1829 return Settings.Global.getInt(mContext.getContentResolver(),
1830 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1831 }
1832
Jim Millerbbf1a742012-07-17 18:30:30 -07001833 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -08001834 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001835 @Override
1836 public void onChange(boolean selfChange) {
1837 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -08001838 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001839 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001840 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001841 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001842 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001843 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001844 };
1845
1846 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -07001847 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -08001848 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -07001849
1850 // prevent a race condition between where we check the flag and where we register the
1851 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -08001852 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001853 if (provisioned != mDeviceProvisioned) {
1854 mDeviceProvisioned = provisioned;
1855 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001856 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001857 }
1858 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001859 }
1860
Jim Millerbbf1a742012-07-17 18:30:30 -07001861 /**
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001862 * Update the state whether Keyguard currently has a lockscreen wallpaper.
1863 *
1864 * @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper.
1865 */
1866 public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001867 checkIsHandlerThread();
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001868 if (hasLockscreenWallpaper != mHasLockscreenWallpaper) {
1869 mHasLockscreenWallpaper = hasLockscreenWallpaper;
1870 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1871 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1872 if (cb != null) {
1873 cb.onHasLockscreenWallpaperChanged(hasLockscreenWallpaper);
1874 }
1875 }
1876 }
1877 }
1878
1879 /**
1880 * @return Whether Keyguard has a lockscreen wallpaper.
1881 */
1882 public boolean hasLockscreenWallpaper() {
1883 return mHasLockscreenWallpaper;
1884 }
1885
1886 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001887 * Handle {@link #MSG_DPM_STATE_CHANGED}
1888 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001889 private void handleDevicePolicyManagerStateChanged() {
Adrian Roos733b6632015-08-21 14:32:35 -07001890 updateFingerprintListeningState();
Jim Millerdcb3d842012-08-23 19:18:12 -07001891 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1892 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1893 if (cb != null) {
1894 cb.onDevicePolicyManagerStateChanged();
1895 }
Jim Millerb0304762012-03-13 20:01:25 -07001896 }
1897 }
1898
Jim Millerbbf1a742012-07-17 18:30:30 -07001899 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001900 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -07001901 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001902 private void handleUserSwitching(int userId, IRemoteCallback reply) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001903 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001904 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1905 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001906 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -07001907 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001908 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001909 try {
1910 reply.sendResult(null);
1911 } catch (RemoteException e) {
1912 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001913 }
1914
Jim Millerbbf1a742012-07-17 18:30:30 -07001915 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001916 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
1917 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001918 private void handleUserSwitchComplete(int userId) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001919 for (int i = 0; i < mCallbacks.size(); i++) {
1920 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1921 if (cb != null) {
1922 cb.onUserSwitchComplete(userId);
1923 }
1924 }
1925 }
1926
1927 /**
Jim Miller90873d52013-09-26 18:11:38 -07001928 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
1929 * keyguard crashes sometime after boot, then it will never receive this
1930 * broadcast and hence not handle the event. This method is ultimately called by
1931 * PhoneWindowManager in this case.
1932 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001933 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001934 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -07001935 }
1936
1937 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001938 * Handle {@link #MSG_BOOT_COMPLETED}
1939 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001940 private void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001941 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001942 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001943 for (int i = 0; i < mCallbacks.size(); i++) {
1944 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1945 if (cb != null) {
1946 cb.onBootCompleted();
1947 }
1948 }
1949 }
1950
1951 /**
Jim Miller5ecd8112013-01-09 18:50:26 -08001952 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001953 * destroyed.
1954 */
1955 public boolean hasBootCompleted() {
1956 return mBootCompleted;
1957 }
1958
1959 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001960 * Handle {@link #MSG_DEVICE_PROVISIONED}
1961 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001962 private void handleDeviceProvisioned() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001963 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001964 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1965 if (cb != null) {
1966 cb.onDeviceProvisioned();
1967 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001968 }
Michael Jurkafff56142012-11-28 16:51:00 -08001969 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001970 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -08001971 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
1972 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001973 }
1974 }
1975
Jim Millerbbf1a742012-07-17 18:30:30 -07001976 /**
1977 * Handle {@link #MSG_PHONE_STATE_CHANGED}
1978 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001979 private void handlePhoneStateChanged(String newState) {
Jim Millerc23024d2010-02-24 15:37:00 -08001980 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001981 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
1982 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
1983 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
1984 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
1985 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
1986 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
1987 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001988 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001989 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1990 if (cb != null) {
1991 cb.onPhoneStateChanged(mPhoneState);
1992 }
Jim Millerc23024d2010-02-24 15:37:00 -08001993 }
1994 }
1995
Jim Millerbbf1a742012-07-17 18:30:30 -07001996 /**
1997 * Handle {@link #MSG_RINGER_MODE_CHANGED}
1998 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001999 private void handleRingerModeChange(int mode) {
Jim Miller47088bb2009-11-24 00:40:16 -08002000 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07002001 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -07002002 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002003 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2004 if (cb != null) {
2005 cb.onRingerModeChanged(mode);
2006 }
Jim Miller47088bb2009-11-24 00:40:16 -08002007 }
2008 }
2009
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002010 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002011 * Handle {@link #MSG_TIME_UPDATE}
2012 */
2013 private void handleTimeUpdate() {
2014 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07002015 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002016 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2017 if (cb != null) {
2018 cb.onTimeChanged();
2019 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002020 }
2021 }
2022
2023 /**
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05002024 * Handle (@line #MSG_TIMEZONE_UPDATE}
2025 */
2026 private void handleTimeZoneUpdate(String timeZone) {
2027 if (DEBUG) Log.d(TAG, "handleTimeZoneUpdate");
2028 for (int i = 0; i < mCallbacks.size(); i++) {
2029 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2030 if (cb != null) {
2031 cb.onTimeZoneChanged(TimeZone.getTimeZone(timeZone));
2032 // Also notify callbacks about time change to remain compatible.
2033 cb.onTimeChanged();
2034 }
2035 }
2036 }
2037
2038 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002039 * Handle {@link #MSG_BATTERY_UPDATE}
2040 */
Jim Millerbbf1a742012-07-17 18:30:30 -07002041 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002042 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07002043 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
2044 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07002045 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002046 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002047 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2048 if (cb != null) {
2049 cb.onRefreshBatteryInfo(status);
2050 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002051 }
2052 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002053 }
2054
2055 /**
Bill Linef81cbd2018-07-05 17:48:49 +08002056 * Handle Telephony status during Boot for CarrierText display policy
2057 */
2058 @VisibleForTesting
2059 void updateTelephonyCapable(boolean capable){
2060 if (capable == mTelephonyCapable) {
2061 return;
2062 }
2063 mTelephonyCapable = capable;
2064 for (WeakReference<KeyguardUpdateMonitorCallback> ref : mCallbacks) {
2065 KeyguardUpdateMonitorCallback cb = ref.get();
2066 if (cb != null) {
2067 cb.onTelephonyCapable(mTelephonyCapable);
2068 }
2069 }
2070 }
2071
2072 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002073 * Handle {@link #MSG_SIM_STATE_CHANGE}
2074 */
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08002075 @VisibleForTesting
Adrian Roos30a2ae62018-04-25 19:09:50 +02002076 void handleSimStateChange(int subId, int slotId, State state) {
2077 checkIsHandlerThread();
Jim Miller52a61332014-11-12 19:29:51 -08002078 if (DEBUG_SIM_STATES) {
2079 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
2080 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002081 }
2082
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002083 boolean becameAbsent = false;
Wink Savillea54bf652014-12-11 13:37:50 -08002084 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08002085 Log.w(TAG, "invalid subId in handleSimStateChange()");
andychou695a7602019-05-16 23:14:00 +08002086 /* Only handle No SIM(ABSENT) and Card Error(CARD_IO_ERROR) due to
2087 * handleServiceStateChange() handle other case */
Bill Linef81cbd2018-07-05 17:48:49 +08002088 if (state == State.ABSENT) {
2089 updateTelephonyCapable(true);
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002090 // Even though the subscription is not valid anymore, we need to notify that the
2091 // SIM card was removed so we can update the UI.
2092 becameAbsent = true;
Brad Ebingere6c6f722018-12-20 21:11:44 -08002093 for (SimData data : mSimDatas.values()) {
2094 // Set the SIM state of all SimData associated with that slot to ABSENT se we
2095 // do not move back into PIN/PUK locked and not detect the change below.
2096 if (data.slotId == slotId) {
2097 data.simState = State.ABSENT;
2098 }
2099 }
andychou695a7602019-05-16 23:14:00 +08002100 } else if (state == State.CARD_IO_ERROR) {
2101 updateTelephonyCapable(true);
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002102 } else {
2103 return;
Bill Linef81cbd2018-07-05 17:48:49 +08002104 }
Jim Miller52a61332014-11-12 19:29:51 -08002105 }
2106
2107 SimData data = mSimDatas.get(subId);
2108 final boolean changed;
2109 if (data == null) {
2110 data = new SimData(state, slotId, subId);
2111 mSimDatas.put(subId, data);
2112 changed = true; // no data yet; force update
2113 } else {
2114 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
2115 data.simState = state;
2116 data.subId = subId;
2117 data.slotId = slotId;
2118 }
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002119 if ((changed || becameAbsent) && state != State.UNKNOWN) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002120 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002121 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2122 if (cb != null) {
Jim Miller52a61332014-11-12 19:29:51 -08002123 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07002124 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002125 }
2126 }
2127 }
2128
Jim Millerbbf1a742012-07-17 18:30:30 -07002129 /**
Etan Cohen47051d82015-07-06 16:19:04 -07002130 * Handle {@link #MSG_SERVICE_STATE_CHANGE}
2131 */
Bill Linef81cbd2018-07-05 17:48:49 +08002132 @VisibleForTesting
2133 void handleServiceStateChange(int subId, ServiceState serviceState) {
Etan Cohen47051d82015-07-06 16:19:04 -07002134 if (DEBUG) {
2135 Log.d(TAG,
2136 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
2137 }
2138
2139 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2140 Log.w(TAG, "invalid subId in handleServiceStateChange()");
2141 return;
Bill Linef81cbd2018-07-05 17:48:49 +08002142 } else {
2143 updateTelephonyCapable(true);
Etan Cohen47051d82015-07-06 16:19:04 -07002144 }
2145
2146 mServiceStates.put(subId, serviceState);
2147
2148 for (int j = 0; j < mCallbacks.size(); j++) {
2149 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
2150 if (cb != null) {
2151 cb.onRefreshCarrierInfo();
2152 }
2153 }
2154 }
2155
Lucas Dupinf8463ee2018-06-11 16:18:15 -07002156 public boolean isKeyguardVisible() {
2157 return mKeyguardIsVisible;
2158 }
2159
Etan Cohen47051d82015-07-06 16:19:04 -07002160 /**
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002161 * Notifies that the visibility state of Keyguard has changed.
2162 *
2163 * <p>Needs to be called from the main thread.
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002164 */
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002165 public void onKeyguardVisibilityChanged(boolean showing) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002166 checkIsHandlerThread();
Kevin Chynb4514d22019-04-15 13:47:25 -07002167 Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002168 mKeyguardIsVisible = showing;
Kevin Chyn6951d3d2019-06-10 14:07:13 -07002169
2170 if (showing) {
2171 mSecureCameraLaunched = false;
2172 }
2173
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002174 for (int i = 0; i < mCallbacks.size(); i++) {
2175 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2176 if (cb != null) {
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002177 cb.onKeyguardVisibilityChangedRaw(showing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002178 }
2179 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002180 updateBiometricListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002181 }
2182
Brian Colonna7fce3802013-09-17 15:51:32 -04002183 /**
Selim Cinek1fcafc42015-07-20 14:39:25 -07002184 * Handle {@link #MSG_KEYGUARD_RESET}
2185 */
2186 private void handleKeyguardReset() {
2187 if (DEBUG) Log.d(TAG, "handleKeyguardReset");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002188 updateBiometricListeningState();
Jorim Jaggi031f7952016-09-01 16:39:26 -07002189 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
2190 }
2191
2192 private boolean resolveNeedsSlowUnlockTransition() {
2193 if (mUserManager.isUserUnlocked(getCurrentUser())) {
2194 return false;
2195 }
2196 Intent homeIntent = new Intent(Intent.ACTION_MAIN)
2197 .addCategory(Intent.CATEGORY_HOME);
2198 ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(homeIntent,
2199 0 /* flags */);
2200 return FALLBACK_HOME_COMPONENT.equals(resolveInfo.getComponentInfo().getComponentName());
Selim Cinek1fcafc42015-07-20 14:39:25 -07002201 }
2202
2203 /**
Adrian Roosb6011622014-05-14 15:52:53 +02002204 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
2205 * @see #sendKeyguardBouncerChanged(boolean)
2206 */
2207 private void handleKeyguardBouncerChanged(int bouncer) {
2208 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
2209 boolean isBouncer = (bouncer == 1);
2210 mBouncer = isBouncer;
Kevin Chynd0381892019-07-11 16:25:36 -07002211
2212 if (isBouncer) {
2213 // If the bouncer is shown, always clear this flag. This can happen in the following
2214 // situations: 1) Default camera with SHOW_WHEN_LOCKED is not chosen yet. 2) Secure
2215 // camera requests dismiss keyguard (tapping on photos for example). When these happen,
2216 // face auth should resume.
2217 mSecureCameraLaunched = false;
2218 }
2219
Adrian Roosb6011622014-05-14 15:52:53 +02002220 for (int i = 0; i < mCallbacks.size(); i++) {
2221 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2222 if (cb != null) {
2223 cb.onKeyguardBouncerChanged(isBouncer);
2224 }
2225 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002226 updateBiometricListeningState();
Adrian Roosb6011622014-05-14 15:52:53 +02002227 }
2228
2229 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04002230 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
2231 */
2232 private void handleReportEmergencyCallAction() {
2233 for (int i = 0; i < mCallbacks.size(); i++) {
2234 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2235 if (cb != null) {
2236 cb.onEmergencyCallAction();
2237 }
2238 }
2239 }
2240
Lucas Dupin4272f442018-01-13 22:00:35 -08002241 private boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002242 final boolean nowPluggedIn = current.isPluggedIn();
2243 final boolean wasPluggedIn = old.isPluggedIn();
Lucas Dupin4272f442018-01-13 22:00:35 -08002244 final boolean stateChangedWhilePluggedIn = wasPluggedIn && nowPluggedIn
Jim Miller16464b82011-10-20 21:10:13 -07002245 && (old.status != current.status);
2246
2247 // change in plug state is always interesting
2248 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002249 return true;
2250 }
2251
Lucas Dupin3fcdd472018-01-19 19:06:45 -08002252 // change in battery level
2253 if (old.level != current.level) {
Jim Miller16464b82011-10-20 21:10:13 -07002254 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002255 }
Adrian Roos76dc5a52015-07-21 16:20:36 -07002256
2257 // change in charging current while plugged in
Adrian Roos0c859ae2015-11-23 16:47:50 -08002258 if (nowPluggedIn && current.maxChargingWattage != old.maxChargingWattage) {
Adrian Roos76dc5a52015-07-21 16:20:36 -07002259 return true;
2260 }
2261
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002262 return false;
2263 }
2264
2265 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07002266 * Remove the given observer's callback.
2267 *
Jim Miller6212cc02012-09-05 17:35:31 -07002268 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002269 */
Jim Miller6212cc02012-09-05 17:35:31 -07002270 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002271 checkIsHandlerThread();
Jim Miller6212cc02012-09-05 17:35:31 -07002272 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
2273 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
2274 if (mCallbacks.get(i).get() == callback) {
2275 mCallbacks.remove(i);
2276 }
2277 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002278 }
2279
2280 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002281 * Register to receive notifications about general keyguard information
2282 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07002283 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002284 */
Jim Millerbbf1a742012-07-17 18:30:30 -07002285 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002286 checkIsHandlerThread();
Jim Miller6212cc02012-09-05 17:35:31 -07002287 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
2288 // Prevent adding duplicate callbacks
2289 for (int i = 0; i < mCallbacks.size(); i++) {
2290 if (mCallbacks.get(i).get() == callback) {
2291 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
2292 new Exception("Called by"));
2293 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07002294 }
2295 }
Jim Miller6212cc02012-09-05 17:35:31 -07002296 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
2297 removeCallback(null); // remove unused references
2298 sendUpdates(callback);
2299 }
2300
Lucas Dupin9e484aa2019-06-24 13:38:00 -07002301 public void setKeyguardBypassController(KeyguardBypassController keyguardBypassController) {
2302 mKeyguardBypassController = keyguardBypassController;
2303 }
2304
Lucas Dupinc12fad32019-05-14 20:59:17 +00002305 public boolean isSwitchingUser() {
2306 return mSwitchingUser;
2307 }
2308
Adrian Roos30a2ae62018-04-25 19:09:50 +02002309 @AnyThread
Evan Rosky18396452016-07-27 15:19:37 -07002310 public void setSwitchingUser(boolean switching) {
Lucas Dupinc12fad32019-05-14 20:59:17 +00002311 mSwitchingUser = switching;
Selim Cinekbbe19242017-12-08 15:42:08 -08002312 // Since this comes in on a binder thread, we need to post if first
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002313 mHandler.post(mUpdateBiometricListeningState);
Evan Rosky18396452016-07-27 15:19:37 -07002314 }
2315
Jim Miller6212cc02012-09-05 17:35:31 -07002316 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
2317 // Notify listener of the current state
2318 callback.onRefreshBatteryInfo(mBatteryStatus);
2319 callback.onTimeChanged();
2320 callback.onRingerModeChanged(mRingMode);
2321 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05002322 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07002323 callback.onClockVisibilityChanged();
Lucas Dupin16cfe452018-02-08 13:14:50 -08002324 callback.onKeyguardVisibilityChangedRaw(mKeyguardIsVisible);
Bill Linef81cbd2018-07-05 17:48:49 +08002325 callback.onTelephonyCapable(mTelephonyCapable);
Jim Miller52a61332014-11-12 19:29:51 -08002326 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
2327 final SimData state = data.getValue();
2328 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
2329 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002330 }
2331
Selim Cinek1fcafc42015-07-20 14:39:25 -07002332 public void sendKeyguardReset() {
2333 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
2334 }
2335
Adrian Roosb6011622014-05-14 15:52:53 +02002336 /**
2337 * @see #handleKeyguardBouncerChanged(int)
2338 */
2339 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
2340 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
2341 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
2342 message.arg1 = showingBouncer ? 1 : 0;
2343 message.sendToTarget();
2344 }
2345
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002346 /**
Jim Miller90d5d462011-11-17 16:57:01 -08002347 * 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 -08002348 * have the information earlier than waiting for the intent
2349 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08002350 *
2351 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
2352 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002353 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02002354 @MainThread
Jim Miller52a61332014-11-12 19:29:51 -08002355 public void reportSimUnlocked(int subId) {
2356 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
Sanket Padawe7e460252017-03-10 16:18:20 -08002357 int slotId = SubscriptionManager.getSlotIndex(subId);
Jim Miller52a61332014-11-12 19:29:51 -08002358 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002359 }
2360
Brian Colonna7fce3802013-09-17 15:51:32 -04002361 /**
2362 * Report that the emergency call button has been pressed and the emergency dialer is
2363 * about to be displayed.
2364 *
2365 * @param bypassHandler runs immediately.
2366 *
2367 * NOTE: Must be called from UI thread if bypassHandler == true.
2368 */
2369 public void reportEmergencyCallAction(boolean bypassHandler) {
2370 if (!bypassHandler) {
2371 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
2372 } else {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002373 checkIsHandlerThread();
Brian Colonna7fce3802013-09-17 15:51:32 -04002374 handleReportEmergencyCallAction();
2375 }
2376 }
2377
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002378 /**
2379 * @return Whether the device is provisioned (whether they have gone through
2380 * the setup wizard)
2381 */
2382 public boolean isDeviceProvisioned() {
2383 return mDeviceProvisioned;
2384 }
2385
Kensuke Matsui21d1bf12017-03-14 13:27:20 +09002386 public ServiceState getServiceState(int subId) {
2387 return mServiceStates.get(subId);
2388 }
2389
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002390 public void clearBiometricRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07002391 mUserFingerprintAuthenticated.clear();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002392 mUserFaceAuthenticated.clear();
2393 mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FINGERPRINT);
2394 mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FACE);
Aran Ink4c0d5602019-06-21 14:27:32 -04002395
2396 for (int i = 0; i < mCallbacks.size(); i++) {
2397 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2398 if (cb != null) {
2399 cb.onBiometricsCleared();
2400 }
2401 }
Jim Millerf41fc962014-06-18 16:33:51 -07002402 }
2403
Jim Miller52a61332014-11-12 19:29:51 -08002404 public boolean isSimPinVoiceSecure() {
2405 // TODO: only count SIMs that handle voice
2406 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07002407 }
2408
Lucas Dupin7156bc72019-05-03 19:37:39 -07002409 /**
2410 * If any SIM cards are currently secure.
2411 * @see #isSimPinSecure(State)
2412 */
Jim Millerdcb3d842012-08-23 19:18:12 -07002413 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08002414 // True if any SIM is pin secure
2415 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
2416 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
2417 }
2418 return false;
2419 }
2420
Jason Monk9ff69bd2014-12-02 16:43:17 -05002421 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08002422 if (mSimDatas.containsKey(subId)) {
2423 return mSimDatas.get(subId).simState;
2424 } else {
2425 return State.UNKNOWN;
2426 }
2427 }
2428
Winson Chung67f5c8b2018-09-24 12:09:19 -07002429 private final TaskStackChangeListener
2430 mTaskStackListener = new TaskStackChangeListener() {
Kevin Chyn2fefd462017-04-28 12:18:19 -07002431 @Override
2432 public void onTaskStackChangedBackground() {
2433 try {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002434 ActivityManager.StackInfo info = ActivityTaskManager.getService().getStackInfo(
Wale Ogunwale68278562017-09-23 17:13:55 -07002435 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
Kevin Chyn2fefd462017-04-28 12:18:19 -07002436 if (info == null) {
2437 return;
2438 }
2439 mHandler.sendMessage(mHandler.obtainMessage(MSG_ASSISTANT_STACK_CHANGED,
2440 info.visible));
2441 } catch (RemoteException e) {
2442 Log.e(TAG, "unable to check task stack", e);
2443 }
2444 }
2445 };
2446
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002447 /**
Richard Choue0381b82018-04-24 03:48:59 +00002448 * @return true if and only if the state has changed for the specified {@code slotId}
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002449 */
Richard Choue0381b82018-04-24 03:48:59 +00002450 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08002451
2452 // This is awful. It exists because there are two APIs for getting the SIM status
2453 // that don't return the complete set of values and have different types. In Keyguard we
2454 // need IccCardConstants, but TelephonyManager would only give us
2455 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08002456 final TelephonyManager tele = TelephonyManager.from(mContext);
Richard Choue0381b82018-04-24 03:48:59 +00002457 int simState = tele.getSimState(slotId);
2458 State state;
2459 try {
2460 state = State.intToState(simState);
2461 } catch(IllegalArgumentException ex) {
2462 Log.w(TAG, "Unknown sim state: " + simState);
2463 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05002464 }
Richard Choue0381b82018-04-24 03:48:59 +00002465 SimData data = mSimDatas.get(subId);
2466 final boolean changed;
2467 if (data == null) {
2468 data = new SimData(state, slotId, subId);
2469 mSimDatas.put(subId, data);
2470 changed = true; // no data yet; force update
2471 } else {
2472 changed = data.simState != state;
2473 data.simState = state;
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002474 }
Richard Choue0381b82018-04-24 03:48:59 +00002475 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07002476 }
2477
Lucas Dupin7156bc72019-05-03 19:37:39 -07002478 /**
2479 * If the {@code state} is currently requiring a SIM PIN, PUK, or is disabled.
2480 */
Jim Millerdcb3d842012-08-23 19:18:12 -07002481 public static boolean isSimPinSecure(IccCardConstants.State state) {
Lucas Dupin7156bc72019-05-03 19:37:39 -07002482 return (state == IccCardConstants.State.PIN_REQUIRED
2483 || state == IccCardConstants.State.PUK_REQUIRED
2484 || state == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07002485 }
Jim Miller8f09fd22013-03-14 19:04:28 -07002486
2487 public DisplayClientState getCachedDisplayClientState() {
2488 return mDisplayClientState;
2489 }
Jim Miller20daffd2013-10-07 14:59:53 -07002490
2491 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
2492 // (KeyguardViewMediator, KeyguardHostView)
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002493 public void dispatchStartedWakingUp() {
2494 synchronized (this) {
2495 mDeviceInteractive = true;
2496 }
2497 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
2498 }
2499
Jorim Jaggi95e40382015-09-16 15:53:42 -07002500 public void dispatchStartedGoingToSleep(int why) {
2501 mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
2502 }
2503
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002504 public void dispatchFinishedGoingToSleep(int why) {
2505 synchronized(this) {
2506 mDeviceInteractive = false;
2507 }
2508 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
2509 }
2510
Jim Miller20daffd2013-10-07 14:59:53 -07002511 public void dispatchScreenTurnedOn() {
2512 synchronized (this) {
2513 mScreenOn = true;
2514 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07002515 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
Jim Miller20daffd2013-10-07 14:59:53 -07002516 }
2517
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002518 public void dispatchScreenTurnedOff() {
Jim Miller20daffd2013-10-07 14:59:53 -07002519 synchronized(this) {
2520 mScreenOn = false;
2521 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07002522 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
Jim Miller20daffd2013-10-07 14:59:53 -07002523 }
2524
Selim Cinek99415392016-09-09 14:58:41 -07002525 public void dispatchDreamingStarted() {
2526 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 1, 0));
2527 }
2528
2529 public void dispatchDreamingStopped() {
2530 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 0, 0));
2531 }
2532
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002533 public boolean isDeviceInteractive() {
2534 return mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -07002535 }
Jim Miller52a61332014-11-12 19:29:51 -08002536
Jorim Jaggi95e40382015-09-16 15:53:42 -07002537 public boolean isGoingToSleep() {
2538 return mGoingToSleep;
2539 }
2540
Jim Miller52a61332014-11-12 19:29:51 -08002541 /**
2542 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
2543 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08002544 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08002545 */
2546 public int getNextSubIdForState(State state) {
2547 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08002548 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08002549 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
2550 for (int i = 0; i < list.size(); i++) {
2551 final SubscriptionInfo info = list.get(i);
2552 final int id = info.getSubscriptionId();
Sanket Padawe7e460252017-03-10 16:18:20 -08002553 int slotId = SubscriptionManager.getSlotIndex(id);
Jim Miller52a61332014-11-12 19:29:51 -08002554 if (state == getSimState(id) && bestSlotId > slotId ) {
2555 resultId = id;
2556 bestSlotId = slotId;
2557 }
2558 }
2559 return resultId;
2560 }
2561
2562 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
2563 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
2564 for (int i = 0; i < list.size(); i++) {
2565 SubscriptionInfo info = list.get(i);
2566 if (subId == info.getSubscriptionId()) return info;
2567 }
2568 return null; // not found
2569 }
Jason Monkab525272015-07-13 17:02:49 -04002570
Alex Chauff7653d2018-02-01 17:18:08 +00002571 /**
2572 * @return a cached version of DevicePolicyManager.isLogoutEnabled()
2573 */
2574 public boolean isLogoutEnabled() {
2575 return mLogoutEnabled;
2576 }
2577
2578 private void updateLogoutEnabled() {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002579 checkIsHandlerThread();
Alex Chauff7653d2018-02-01 17:18:08 +00002580 boolean logoutEnabled = mDevicePolicyManager.isLogoutEnabled();
2581 if (mLogoutEnabled != logoutEnabled) {
2582 mLogoutEnabled = logoutEnabled;
2583 for (int i = 0; i < mCallbacks.size(); i++) {
2584 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2585 if (cb != null) {
2586 cb.onLogoutEnabledChanged();
2587 }
2588 }
2589 }
2590 }
2591
Adrian Roos30a2ae62018-04-25 19:09:50 +02002592 private void checkIsHandlerThread() {
2593 if (sDisableHandlerCheckForTesting) {
2594 return;
2595 }
2596 if (!mHandler.getLooper().isCurrentThread()) {
2597 Log.wtf(TAG, "must call on mHandler's thread "
2598 + mHandler.getLooper().getThread() + ", not " + Thread.currentThread());
2599 }
2600 }
2601
2602 /**
2603 * Turn off the handler check for testing.
2604 *
2605 * This is necessary because currently tests are not too careful about which thread they call
2606 * into this class on.
2607 *
2608 * Note that this must be called before scheduling any work involving KeyguardUpdateMonitor
2609 * instances.
2610 *
2611 * TODO: fix the tests and remove this.
2612 */
2613 @VisibleForTesting
2614 public static void disableHandlerCheckForTesting(Instrumentation instrumentation) {
2615 Preconditions.checkNotNull(instrumentation, "Must only call this method in tests!");
2616 // Don't need synchronization here *if* the callers follow the contract and call this only
2617 // before scheduling work for KeyguardUpdateMonitor on other threads, because the scheduling
2618 // of that work forces a happens-before relationship.
2619 sDisableHandlerCheckForTesting = true;
2620 }
2621
Jason Monkab525272015-07-13 17:02:49 -04002622 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2623 pw.println("KeyguardUpdateMonitor state:");
2624 pw.println(" SIM States:");
2625 for (SimData data : mSimDatas.values()) {
2626 pw.println(" " + data.toString());
2627 }
2628 pw.println(" Subs:");
2629 if (mSubscriptionInfo != null) {
2630 for (int i = 0; i < mSubscriptionInfo.size(); i++) {
2631 pw.println(" " + mSubscriptionInfo.get(i));
2632 }
2633 }
2634 pw.println(" Service states:");
2635 for (int subId : mServiceStates.keySet()) {
2636 pw.println(" " + subId + "=" + mServiceStates.get(subId));
2637 }
Jim Millerd72d5ac2015-09-29 18:55:32 -07002638 if (mFpm != null && mFpm.isHardwareDetected()) {
2639 final int userId = ActivityManager.getCurrentUser();
2640 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
2641 pw.println(" Fingerprint state (user=" + userId + ")");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002642 pw.println(" allowed=" + isUnlockingWithBiometricAllowed());
Jim Millerd72d5ac2015-09-29 18:55:32 -07002643 pw.println(" auth'd=" + mUserFingerprintAuthenticated.get(userId));
2644 pw.println(" authSinceBoot="
2645 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
2646 pw.println(" disabled(DPM)=" + isFingerprintDisabled(userId));
2647 pw.println(" possible=" + isUnlockWithFingerprintPossible(userId));
Adrian Roos2aaf9442018-11-20 16:57:33 +01002648 pw.println(" listening: actual=" + mFingerprintRunningState
2649 + " expected=" + (shouldListenForFingerprint() ? 1 : 0));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002650 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002651 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
2652 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07002653 if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002654 final int userId = ActivityManager.getCurrentUser();
2655 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
2656 pw.println(" Face authentication state (user=" + userId + ")");
2657 pw.println(" allowed=" + isUnlockingWithBiometricAllowed());
2658 pw.println(" auth'd=" + mUserFaceAuthenticated.get(userId));
2659 pw.println(" authSinceBoot="
2660 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
2661 pw.println(" disabled(DPM)=" + isFaceDisabled(userId));
2662 pw.println(" possible=" + isUnlockWithFacePossible(userId));
2663 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
2664 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
Lucas Dupin7d95f152019-07-17 16:25:54 -07002665 pw.println(" enabledByUser=" + mFaceSettingEnabledForUser.get(userId));
Kevin Chynd0381892019-07-11 16:25:36 -07002666 pw.println(" mSecureCameraLaunched=" + mSecureCameraLaunched);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002667 }
Jason Monkab525272015-07-13 17:02:49 -04002668 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002669}