blob: 32e447badcb744301a4ab670f56eeb4e1d3f5b48 [file] [log] [blame]
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jim Miller5ecd8112013-01-09 18:50:26 -080017package com.android.keyguard;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080018
Wale Ogunwale68278562017-09-23 17:13:55 -070019import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
20import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Jorim Jaggidadafd42016-09-30 07:20:25 -070021import static android.content.Intent.ACTION_USER_UNLOCKED;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070022import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
23import static android.os.BatteryManager.BATTERY_STATUS_FULL;
24import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
25import static android.os.BatteryManager.EXTRA_HEALTH;
26import static android.os.BatteryManager.EXTRA_LEVEL;
27import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
28import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
29import static android.os.BatteryManager.EXTRA_PLUGGED;
30import static android.os.BatteryManager.EXTRA_STATUS;
31
Adrian Roos30a2ae62018-04-25 19:09:50 +020032import android.annotation.AnyThread;
33import android.annotation.MainThread;
Jorim Jaggiccdfa932015-04-13 16:29:48 -070034import android.app.ActivityManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070035import android.app.ActivityTaskManager;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020036import android.app.AlarmManager;
Adrian Roos30a2ae62018-04-25 19:09:50 +020037import android.app.Instrumentation;
Jim Miller8f09fd22013-03-14 19:04:28 -070038import android.app.PendingIntent;
Sudheer Shanka2c4522c2016-08-27 20:53:28 -070039import android.app.UserSwitchObserver;
Jim Millerb0304762012-03-13 20:01:25 -070040import android.app.admin.DevicePolicyManager;
Adrian Roos46842d92014-03-27 14:58:03 +010041import android.app.trust.TrustManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080042import android.content.BroadcastReceiver;
Jorim Jaggi031f7952016-09-01 16:39:26 -070043import android.content.ComponentName;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080044import android.content.Context;
45import android.content.Intent;
46import android.content.IntentFilter;
Adrian Roosca8a2162017-08-17 19:00:58 +020047import android.content.pm.IPackageManager;
Jorim Jaggi031f7952016-09-01 16:39:26 -070048import android.content.pm.PackageManager;
49import android.content.pm.ResolveInfo;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080050import android.database.ContentObserver;
Kevin Chynb7b54a62018-09-28 18:48:12 -070051import android.hardware.biometrics.BiometricManager;
Kevin Chyn56233ab2018-09-20 17:10:57 -070052import android.hardware.biometrics.BiometricSourceType;
Kevin Chynb7b54a62018-09-28 18:48:12 -070053import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
Gilad Brettercb51b8b2018-03-22 17:04:51 +020054import android.hardware.face.FaceManager;
Jorim Jaggi86bed402015-08-20 18:20:02 -070055import android.hardware.fingerprint.FingerprintManager;
56import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
57import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
Jim Miller47088bb2009-11-24 00:40:16 -080058import android.media.AudioManager;
Jim Miller79a444a2011-02-15 15:02:11 -080059import android.os.BatteryManager;
Jim Miller9f0753f2015-03-23 23:59:22 -070060import android.os.CancellationSignal;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080061import android.os.Handler;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070062import android.os.IRemoteCallback;
Jason Monk7bb59302018-05-10 19:38:18 -070063import android.os.Looper;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080064import android.os.Message;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070065import android.os.RemoteException;
Adrian Roosca8a2162017-08-17 19:00:58 +020066import android.os.ServiceManager;
Nick Desaulniers1d396752016-07-25 15:05:33 -070067import android.os.Trace;
Amith Yamasanie8e93a12013-05-09 18:12:30 -070068import android.os.UserHandle;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070069import android.os.UserManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080070import android.provider.Settings;
Kevin Chyn36778ff2017-09-07 19:55:38 -070071import android.service.dreams.DreamService;
72import android.service.dreams.IDreamManager;
Etan Cohen47051d82015-07-06 16:19:04 -070073import android.telephony.ServiceState;
Jim Miller52a61332014-11-12 19:29:51 -080074import android.telephony.SubscriptionInfo;
Jim Miller52a61332014-11-12 19:29:51 -080075import android.telephony.SubscriptionManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -080076import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Jim Millerc23024d2010-02-24 15:37:00 -080077import android.telephony.TelephonyManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080078import android.util.Log;
Adrian Roos46842d92014-03-27 14:58:03 +010079import android.util.SparseBooleanArray;
80
Lucas Dupin7517b5d2017-08-22 12:51:25 -070081import com.android.internal.annotations.VisibleForTesting;
Jorim Jaggi86bed402015-08-20 18:20:02 -070082import com.android.internal.telephony.IccCardConstants;
83import com.android.internal.telephony.IccCardConstants.State;
84import com.android.internal.telephony.PhoneConstants;
85import com.android.internal.telephony.TelephonyIntents;
Adrian Roos30a2ae62018-04-25 19:09:50 +020086import com.android.internal.util.Preconditions;
Adrian Roosb5e47222015-08-14 15:53:06 -070087import com.android.internal.widget.LockPatternUtils;
Bill Linef81cbd2018-07-05 17:48:49 +080088import com.android.settingslib.WirelessUtils;
Winson Chung2cf6ad82017-11-09 17:36:59 -080089import com.android.systemui.shared.system.ActivityManagerWrapper;
Winson Chung67f5c8b2018-09-24 12:09:19 -070090import com.android.systemui.shared.system.TaskStackChangeListener;
Kevin Chyn1123ba72018-10-26 10:34:06 -070091
Kevin Chyn36778ff2017-09-07 19:55:38 -070092import com.google.android.collect.Lists;
93
Jason Monkab525272015-07-13 17:02:49 -040094import java.io.FileDescriptor;
95import java.io.PrintWriter;
Jim Millerdcb3d842012-08-23 19:18:12 -070096import java.lang.ref.WeakReference;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080097import java.util.ArrayList;
Jim Miller52a61332014-11-12 19:29:51 -080098import java.util.HashMap;
99import java.util.List;
100import java.util.Map.Entry;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500101import java.util.TimeZone;
Lucas Dupin3d053532019-01-29 12:35:22 -0800102import java.util.function.Consumer;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800103
104/**
105 * Watches for updates that may be interesting to the keyguard, and provides
106 * the up to date information as well as a registration for callbacks that care
107 * to be updated.
108 *
109 * Note: under time crunch, this has been extended to include some stuff that
110 * doesn't really belong here. see {@link #handleBatteryUpdate} where it shutdowns
Jim Miller258341c2012-08-30 16:50:10 -0700111 * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()}
112 * and {@link #clearFailedUnlockAttempts()}. Maybe we should rename this 'KeyguardContext'...
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800113 */
Adrian Roos46842d92014-03-27 14:58:03 +0100114public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800115
Jim Millerbbf1a742012-07-17 18:30:30 -0700116 private static final String TAG = "KeyguardUpdateMonitor";
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100117 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller52a61332014-11-12 19:29:51 -0800118 private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
Jim Millerbbf1a742012-07-17 18:30:30 -0700119 private static final int LOW_BATTERY_THRESHOLD = 20;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800120
Jorim Jaggie7b12522014-08-06 16:41:21 +0200121 private static final String ACTION_FACE_UNLOCK_STARTED
122 = "com.android.facelock.FACE_UNLOCK_STARTED";
123 private static final String ACTION_FACE_UNLOCK_STOPPED
124 = "com.android.facelock.FACE_UNLOCK_STOPPED";
125
Jim Millerbbf1a742012-07-17 18:30:30 -0700126 // Callback messages
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800127 private static final int MSG_TIME_UPDATE = 301;
128 private static final int MSG_BATTERY_UPDATE = 302;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800129 private static final int MSG_SIM_STATE_CHANGE = 304;
Jim Miller47088bb2009-11-24 00:40:16 -0800130 private static final int MSG_RINGER_MODE_CHANGED = 305;
Jim Millerc23024d2010-02-24 15:37:00 -0800131 private static final int MSG_PHONE_STATE_CHANGED = 306;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700132 private static final int MSG_DEVICE_PROVISIONED = 308;
Jim Miller57375342012-09-09 15:20:31 -0700133 private static final int MSG_DPM_STATE_CHANGED = 309;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500134 private static final int MSG_USER_SWITCHING = 310;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700135 private static final int MSG_KEYGUARD_RESET = 312;
Jim Millerf41fc962014-06-18 16:33:51 -0700136 private static final int MSG_BOOT_COMPLETED = 313;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500137 private static final int MSG_USER_SWITCH_COMPLETE = 314;
Jim Millerf41fc962014-06-18 16:33:51 -0700138 private static final int MSG_USER_INFO_CHANGED = 317;
139 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700140 private static final int MSG_STARTED_WAKING_UP = 319;
141 private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700142 private static final int MSG_STARTED_GOING_TO_SLEEP = 321;
Adrian Roosb6011622014-05-14 15:52:53 +0200143 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700144 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
145 private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
Jason Monk052082c2015-06-11 11:35:23 -0400146 private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
Etan Cohen47051d82015-07-06 16:19:04 -0700147 private static final int MSG_SERVICE_STATE_CHANGE = 330;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700148 private static final int MSG_SCREEN_TURNED_ON = 331;
149 private static final int MSG_SCREEN_TURNED_OFF = 332;
Selim Cinek99415392016-09-09 14:58:41 -0700150 private static final int MSG_DREAMING_STATE_CHANGED = 333;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700151 private static final int MSG_USER_UNLOCKED = 334;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700152 private static final int MSG_ASSISTANT_STACK_CHANGED = 335;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200153 private static final int MSG_BIOMETRIC_AUTHENTICATION_CONTINUE = 336;
Alex Chauff7653d2018-02-01 17:18:08 +0000154 private static final int MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED = 337;
Bill Linef81cbd2018-07-05 17:48:49 +0800155 private static final int MSG_TELEPHONY_CAPABLE = 338;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500156 private static final int MSG_TIMEZONE_UPDATE = 339;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800157
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200158 /** Biometric authentication state: Not listening. */
159 private static final int BIOMETRIC_STATE_STOPPED = 0;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700160
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200161 /** Biometric authentication state: Listening. */
162 private static final int BIOMETRIC_STATE_RUNNING = 1;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700163
164 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200165 * Biometric authentication: Cancelling and waiting for the relevant biometric service to
Jorim Jaggi86bed402015-08-20 18:20:02 -0700166 * send us the confirmation that cancellation has happened.
167 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200168 private static final int BIOMETRIC_STATE_CANCELLING = 2;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700169
170 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200171 * Biometric state: During cancelling we got another request to start listening, so when we
Jorim Jaggi86bed402015-08-20 18:20:02 -0700172 * receive the cancellation done signal, we should start listening again.
173 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200174 private static final int BIOMETRIC_STATE_CANCELLING_RESTARTING = 3;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700175
Adrian Roos0c859ae2015-11-23 16:47:50 -0800176 private static final int DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT = 5000000;
177
Jorim Jaggi031f7952016-09-01 16:39:26 -0700178 private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName(
179 "com.android.settings", "com.android.settings.FallbackHome");
180
Adrian Roosca8a2162017-08-17 19:00:58 +0200181
182 /**
183 * If true, the system is in the half-boot-to-decryption-screen state.
184 * Prudently disable lockscreen.
185 */
186 public static final boolean CORE_APPS_ONLY;
187 static {
188 try {
189 CORE_APPS_ONLY = IPackageManager.Stub.asInterface(
190 ServiceManager.getService("package")).isOnlyCoreApps();
191 } catch (RemoteException e) {
192 throw e.rethrowFromSystemServer();
193 }
194 }
195
Jim Millerdcb3d842012-08-23 19:18:12 -0700196 private static KeyguardUpdateMonitor sInstance;
197
Jim Millerbbf1a742012-07-17 18:30:30 -0700198 private final Context mContext;
Kevin Chynfdfd2d32019-03-01 14:52:15 -0800199 private final boolean mIsPrimaryUser;
Jim Miller52a61332014-11-12 19:29:51 -0800200 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
Etan Cohen47051d82015-07-06 16:19:04 -0700201 HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700202
Jim Millerbbf1a742012-07-17 18:30:30 -0700203 private int mRingMode;
204 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400205 private boolean mKeyguardIsVisible;
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700206 private boolean mKeyguardGoingAway;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700207 private boolean mGoingToSleep;
Adrian Roosb6011622014-05-14 15:52:53 +0200208 private boolean mBouncer;
Lucas Dupine0516d52019-02-05 17:54:06 -0500209 private boolean mAuthInterruptActive;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800210 private boolean mBootCompleted;
Jorim Jaggi031f7952016-09-01 16:39:26 -0700211 private boolean mNeedsSlowUnlockTransition;
Jorim Jaggid11d1a92016-08-16 16:02:32 -0700212 private boolean mHasLockscreenWallpaper;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700213 private boolean mAssistantVisible;
214 private boolean mKeyguardOccluded;
Bill Linef81cbd2018-07-05 17:48:49 +0800215 @VisibleForTesting
216 protected boolean mTelephonyCapable;
Jim Millerbbf1a742012-07-17 18:30:30 -0700217
Jim Millerdcb3d842012-08-23 19:18:12 -0700218 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700219 private boolean mDeviceProvisioned;
220
Jim Millerdcb3d842012-08-23 19:18:12 -0700221 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700222 private BatteryStatus mBatteryStatus;
223
Lucas Dupin3d053532019-01-29 12:35:22 -0800224 @VisibleForTesting
225 protected StrongAuthTracker mStrongAuthTracker;
Jim Millerbbf1a742012-07-17 18:30:30 -0700226
Jim Miller6212cc02012-09-05 17:35:31 -0700227 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700228 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800229 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700230
Brian Colonnaa5239892013-04-15 11:45:40 -0400231 private boolean mSwitchingUser;
232
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700233 private boolean mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -0700234 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800235 private SubscriptionManager mSubscriptionManager;
236 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700237 private TrustManager mTrustManager;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700238 private UserManager mUserManager;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200239 private int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
240 private int mFaceRunningState = BIOMETRIC_STATE_STOPPED;
Michal Karpinskic52f8672016-11-18 11:32:45 +0000241 private LockPatternUtils mLockPatternUtils;
Kevin Chyn36778ff2017-09-07 19:55:38 -0700242 private final IDreamManager mDreamManager;
243 private boolean mIsDreaming;
Alex Chauff7653d2018-02-01 17:18:08 +0000244 private final DevicePolicyManager mDevicePolicyManager;
245 private boolean mLogoutEnabled;
Jim Miller20daffd2013-10-07 14:59:53 -0700246
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700247 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200248 * Short delay before restarting biometric authentication after a successful try
249 * This should be slightly longer than the time between on<biometric>Authenticated
250 * (e.g. onFingerprintAuthenticated) and setKeyguardGoingAway(true).
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700251 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200252 private static final int BIOMETRIC_CONTINUE_DELAY_MS = 500;
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700253
Kevin Chyn0c45b072017-04-24 16:27:11 -0700254 // If FP daemon dies, keyguard should retry after a short delay
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200255 private int mHardwareFingerprintUnavailableRetryCount = 0;
256 private int mHardwareFaceUnavailableRetryCount = 0;
Kevin Chyn0c45b072017-04-24 16:27:11 -0700257 private static final int HW_UNAVAILABLE_TIMEOUT = 3000; // ms
258 private static final int HW_UNAVAILABLE_RETRY_MAX = 3;
259
Jason Monk7bb59302018-05-10 19:38:18 -0700260 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700261 @Override
262 public void handleMessage(Message msg) {
263 switch (msg.what) {
264 case MSG_TIME_UPDATE:
265 handleTimeUpdate();
266 break;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500267 case MSG_TIMEZONE_UPDATE:
268 handleTimeZoneUpdate((String) msg.obj);
269 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700270 case MSG_BATTERY_UPDATE:
271 handleBatteryUpdate((BatteryStatus) msg.obj);
272 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700273 case MSG_SIM_STATE_CHANGE:
Jim Miller52a61332014-11-12 19:29:51 -0800274 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700275 break;
276 case MSG_RINGER_MODE_CHANGED:
277 handleRingerModeChange(msg.arg1);
278 break;
279 case MSG_PHONE_STATE_CHANGED:
Adrian Roosb6011622014-05-14 15:52:53 +0200280 handlePhoneStateChanged((String) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700281 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700282 case MSG_DEVICE_PROVISIONED:
283 handleDeviceProvisioned();
284 break;
285 case MSG_DPM_STATE_CHANGED:
286 handleDevicePolicyManagerStateChanged();
287 break;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500288 case MSG_USER_SWITCHING:
Adrian Roosb6011622014-05-14 15:52:53 +0200289 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
Chris Wrenf41c61b2012-11-29 15:19:54 -0500290 break;
291 case MSG_USER_SWITCH_COMPLETE:
292 handleUserSwitchComplete(msg.arg1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700293 break;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700294 case MSG_KEYGUARD_RESET:
295 handleKeyguardReset();
296 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200297 case MSG_KEYGUARD_BOUNCER_CHANGED:
298 handleKeyguardBouncerChanged(msg.arg1);
299 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800300 case MSG_BOOT_COMPLETED:
301 handleBootCompleted();
302 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700303 case MSG_USER_INFO_CHANGED:
304 handleUserInfoChanged(msg.arg1);
305 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400306 case MSG_REPORT_EMERGENCY_CALL_ACTION:
307 handleReportEmergencyCallAction();
308 break;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700309 case MSG_STARTED_GOING_TO_SLEEP:
310 handleStartedGoingToSleep(msg.arg1);
311 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700312 case MSG_FINISHED_GOING_TO_SLEEP:
313 handleFinishedGoingToSleep(msg.arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700314 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700315 case MSG_STARTED_WAKING_UP:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700316 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_STARTED_WAKING_UP");
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700317 handleStartedWakingUp();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700318 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -0700319 break;
Jorim Jaggie7b12522014-08-06 16:41:21 +0200320 case MSG_FACE_UNLOCK_STATE_CHANGED:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700321 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_FACE_UNLOCK_STATE_CHANGED");
Adrian Roos4a410172014-08-20 17:41:44 +0200322 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
Nick Desaulniers1d396752016-07-25 15:05:33 -0700323 Trace.endSection();
Jorim Jaggie7b12522014-08-06 16:41:21 +0200324 break;
Jim Miller52a61332014-11-12 19:29:51 -0800325 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
326 handleSimSubscriptionInfoChanged();
327 break;
Jason Monk052082c2015-06-11 11:35:23 -0400328 case MSG_AIRPLANE_MODE_CHANGED:
329 handleAirplaneModeChanged();
330 break;
Etan Cohen47051d82015-07-06 16:19:04 -0700331 case MSG_SERVICE_STATE_CHANGE:
332 handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
333 break;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700334 case MSG_SCREEN_TURNED_ON:
335 handleScreenTurnedOn();
336 break;
337 case MSG_SCREEN_TURNED_OFF:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700338 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_SCREEN_TURNED_ON");
Jorim Jaggif1518da2015-07-30 11:56:36 -0700339 handleScreenTurnedOff();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700340 Trace.endSection();
Jorim Jaggif1518da2015-07-30 11:56:36 -0700341 break;
Selim Cinek99415392016-09-09 14:58:41 -0700342 case MSG_DREAMING_STATE_CHANGED:
343 handleDreamingStateChanged(msg.arg1);
344 break;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700345 case MSG_USER_UNLOCKED:
346 handleUserUnlocked();
347 break;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700348 case MSG_ASSISTANT_STACK_CHANGED:
Lucas Dupin3d053532019-01-29 12:35:22 -0800349 setAssistantVisible((boolean) msg.obj);
Kevin Chyn2fefd462017-04-28 12:18:19 -0700350 break;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200351 case MSG_BIOMETRIC_AUTHENTICATION_CONTINUE:
352 updateBiometricListeningState();
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700353 break;
Alex Chauff7653d2018-02-01 17:18:08 +0000354 case MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED:
355 updateLogoutEnabled();
356 break;
Bill Linef81cbd2018-07-05 17:48:49 +0800357 case MSG_TELEPHONY_CAPABLE:
Lucas Dupin3d053532019-01-29 12:35:22 -0800358 updateTelephonyCapable((boolean) msg.obj);
Bill Linef81cbd2018-07-05 17:48:49 +0800359 break;
Jason Monk7bb59302018-05-10 19:38:18 -0700360 default:
361 super.handleMessage(msg);
362 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700363 }
364 }
365 };
366
Kevin Chynb7b54a62018-09-28 18:48:12 -0700367 private boolean mFaceSettingEnabledForUser;
368 private BiometricManager mBiometricManager;
369 private IBiometricEnabledOnKeyguardCallback mBiometricEnabledCallback =
370 new IBiometricEnabledOnKeyguardCallback.Stub() {
371 @Override
372 public void onChanged(BiometricSourceType type, boolean enabled) throws RemoteException {
373 if (type == BiometricSourceType.FACE) {
374 mFaceSettingEnabledForUser = enabled;
375 }
376 }
377 };
378
Wink Savilled09c4ca2014-11-22 10:08:16 -0800379 private OnSubscriptionsChangedListener mSubscriptionListener =
380 new OnSubscriptionsChangedListener() {
Jim Miller52a61332014-11-12 19:29:51 -0800381 @Override
Wink Savilled09c4ca2014-11-22 10:08:16 -0800382 public void onSubscriptionsChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800383 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
384 }
385 };
386
Adrian Roos46842d92014-03-27 14:58:03 +0100387 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200388 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Jim Miller9f0753f2015-03-23 23:59:22 -0700389 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200390 private SparseBooleanArray mUserFaceAuthenticated = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200391 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100392
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700393 private static int sCurrentUser;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200394 private Runnable mUpdateBiometricListeningState = this::updateBiometricListeningState;
Adrian Roos30a2ae62018-04-25 19:09:50 +0200395 private static boolean sDisableHandlerCheckForTesting;
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700396
397 public synchronized static void setCurrentUser(int currentUser) {
398 sCurrentUser = currentUser;
399 }
400
401 public synchronized static int getCurrentUser() {
402 return sCurrentUser;
403 }
404
Adrian Roos46842d92014-03-27 14:58:03 +0100405 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700406 public void onTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200407 checkIsHandlerThread();
Adrian Roos46842d92014-03-27 14:58:03 +0100408 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200409 for (int i = 0; i < mCallbacks.size(); i++) {
410 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
411 if (cb != null) {
412 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700413 if (enabled && flags != 0) {
414 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200415 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200416 }
417 }
Adrian Roos46842d92014-03-27 14:58:03 +0100418 }
419
Lucas Dupinef886542018-01-03 16:03:07 -0800420 @Override
421 public void onTrustError(CharSequence message) {
422 dispatchErrorMessage(message);
423 }
424
Adrian Roos30a2ae62018-04-25 19:09:50 +0200425 private void handleSimSubscriptionInfoChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800426 if (DEBUG_SIM_STATES) {
427 Log.v(TAG, "onSubscriptionInfoChanged()");
Wink Savilled09c4ca2014-11-22 10:08:16 -0800428 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
429 if (sil != null) {
430 for (SubscriptionInfo subInfo : sil) {
431 Log.v(TAG, "SubInfo:" + subInfo);
432 }
433 } else {
434 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800435 }
436 }
437 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
438
439 // Hack level over 9000: Because the subscription id is not yet valid when we see the
440 // first update in handleSimStateChange, we need to force refresh all all SIM states
441 // so the subscription id for them is consistent.
Richard Choue0381b82018-04-24 03:48:59 +0000442 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
443 for (int i = 0; i < subscriptionInfos.size(); i++) {
444 SubscriptionInfo info = subscriptionInfos.get(i);
445 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
446 if (changed) {
447 changedSubscriptions.add(info);
448 }
449 }
450 for (int i = 0; i < changedSubscriptions.size(); i++) {
451 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800452 for (int j = 0; j < mCallbacks.size(); j++) {
453 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
454 if (cb != null) {
455 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
456 }
457 }
458 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500459 for (int j = 0; j < mCallbacks.size(); j++) {
460 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
461 if (cb != null) {
462 cb.onRefreshCarrierInfo();
463 }
464 }
Jim Miller52a61332014-11-12 19:29:51 -0800465 }
466
Jason Monk052082c2015-06-11 11:35:23 -0400467 private void handleAirplaneModeChanged() {
468 for (int j = 0; j < mCallbacks.size(); j++) {
469 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
470 if (cb != null) {
471 cb.onRefreshCarrierInfo();
472 }
473 }
474 }
475
Wink Savilled09c4ca2014-11-22 10:08:16 -0800476 /** @return List of SubscriptionInfo records, maybe empty but never null */
Adrian Roos316bf542016-08-23 17:53:07 +0200477 public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800478 List<SubscriptionInfo> sil = mSubscriptionInfo;
479 if (sil == null || forceReload) {
480 sil = mSubscriptionManager.getActiveSubscriptionInfoList();
481 }
482 if (sil == null) {
483 // getActiveSubscriptionInfoList was null callers expect an empty list.
484 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
485 } else {
486 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800487 }
488 return mSubscriptionInfo;
489 }
490
Adrian Roos7861c662014-07-25 15:37:28 +0200491 @Override
492 public void onTrustManagedChanged(boolean managed, int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200493 checkIsHandlerThread();
Adrian Roos7861c662014-07-25 15:37:28 +0200494 mUserTrustIsManaged.put(userId, managed);
495
496 for (int i = 0; i < mCallbacks.size(); i++) {
497 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
498 if (cb != null) {
499 cb.onTrustManagedChanged(userId);
500 }
501 }
502 }
503
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700504 /**
505 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is goingAway
506 * @param goingAway
507 */
508 public void setKeyguardGoingAway(boolean goingAway) {
509 mKeyguardGoingAway = goingAway;
Kevin Chyne22f1342017-09-26 10:03:38 -0700510 updateFingerprintListeningState();
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700511 }
512
Kevin Chyn2fefd462017-04-28 12:18:19 -0700513 /**
514 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is occluded
515 * @param occluded
516 */
517 public void setKeyguardOccluded(boolean occluded) {
518 mKeyguardOccluded = occluded;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200519 updateBiometricListeningState();
Kevin Chyn2fefd462017-04-28 12:18:19 -0700520 }
521
Kevin Chyn36778ff2017-09-07 19:55:38 -0700522 /**
523 * @return a cached version of DreamManager.isDreaming()
524 */
525 public boolean isDreaming() {
526 return mIsDreaming;
527 }
528
529 /**
530 * If the device is dreaming, awakens the device
531 */
532 public void awakenFromDream() {
533 if (mIsDreaming && mDreamManager != null) {
534 try {
535 mDreamManager.awaken();
536 } catch (RemoteException e) {
537 Log.e(TAG, "Unable to awaken from dream");
538 }
539 }
540 }
541
Lucas Dupin3d053532019-01-29 12:35:22 -0800542 @VisibleForTesting
543 protected void onFingerprintAuthenticated(int userId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700544 Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
Jim Miller9f0753f2015-03-23 23:59:22 -0700545 mUserFingerprintAuthenticated.put(userId, true);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700546 // Update/refresh trust state only if user can skip bouncer
547 if (getUserCanSkipBouncer(userId)) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200548 mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FINGERPRINT);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700549 }
Kevin Chyn625a0142017-04-10 14:53:59 -0700550 // Don't send cancel if authentication succeeds
551 mFingerprintCancelSignal = null;
Jim Millerf41fc962014-06-18 16:33:51 -0700552 for (int i = 0; i < mCallbacks.size(); i++) {
553 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
554 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200555 cb.onBiometricAuthenticated(userId, BiometricSourceType.FINGERPRINT);
Jim Millerf41fc962014-06-18 16:33:51 -0700556 }
557 }
Kevin Chyn2fefd462017-04-28 12:18:19 -0700558
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200559 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE),
560 BIOMETRIC_CONTINUE_DELAY_MS);
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700561
Kevin Chyn2fefd462017-04-28 12:18:19 -0700562 // Only authenticate fingerprint once when assistant is visible
563 mAssistantVisible = false;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700564
Nick Desaulniers1d396752016-07-25 15:05:33 -0700565 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700566 }
567
Jim Millerce7eb6d2015-04-03 19:29:13 -0700568 private void handleFingerprintAuthFailed() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700569 for (int i = 0; i < mCallbacks.size(); i++) {
570 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
571 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200572 cb.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700573 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700574 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200575 handleFingerprintHelp(-1, mContext.getString(R.string.kg_fingerprint_not_recognized));
Jim Millerce7eb6d2015-04-03 19:29:13 -0700576 }
Jim Millerf41fc962014-06-18 16:33:51 -0700577
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700578 private void handleFingerprintAcquired(int acquireInfo) {
579 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
580 return;
581 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -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.onBiometricAcquired(BiometricSourceType.FINGERPRINT);
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700586 }
587 }
588 }
589
Jim Miller837fa7e2016-08-08 20:16:22 -0700590 private void handleFingerprintAuthenticated(int authUserId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700591 Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
Jim Millerf41fc962014-06-18 16:33:51 -0700592 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700593 final int userId;
594 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800595 userId = ActivityManager.getService().getCurrentUser().id;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700596 } catch (RemoteException e) {
597 Log.e(TAG, "Failed to get current user id: ", e);
598 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700599 }
Jim Miller837fa7e2016-08-08 20:16:22 -0700600 if (userId != authUserId) {
601 Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId);
602 return;
603 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700604 if (isFingerprintDisabled(userId)) {
605 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
606 return;
607 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700608 onFingerprintAuthenticated(userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700609 } finally {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200610 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Jim Millerf41fc962014-06-18 16:33:51 -0700611 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700612 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700613 }
614
Jim Miller9f0753f2015-03-23 23:59:22 -0700615 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700616 for (int i = 0; i < mCallbacks.size(); i++) {
617 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
618 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200619 cb.onBiometricHelp(msgId, helpString, BiometricSourceType.FINGERPRINT);
Jim Miller9f0753f2015-03-23 23:59:22 -0700620 }
621 }
622 }
623
Kevin Chyn0c45b072017-04-24 16:27:11 -0700624 private Runnable mRetryFingerprintAuthentication = new Runnable() {
625 @Override
626 public void run() {
627 Log.w(TAG, "Retrying fingerprint after HW unavailable, attempt " +
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200628 mHardwareFingerprintUnavailableRetryCount);
Kevin Chyn0c45b072017-04-24 16:27:11 -0700629 updateFingerprintListeningState();
630 }
631 };
632
Jim Miller9f0753f2015-03-23 23:59:22 -0700633 private void handleFingerprintError(int msgId, String errString) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700634 if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200635 && mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
636 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Kevin Chyn1123ba72018-10-26 10:34:06 -0700637 updateFingerprintListeningState();
Jorim Jaggi86bed402015-08-20 18:20:02 -0700638 } else {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200639 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Jorim Jaggi86bed402015-08-20 18:20:02 -0700640 }
Kevin Chyn0c45b072017-04-24 16:27:11 -0700641
642 if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200643 if (mHardwareFingerprintUnavailableRetryCount < HW_UNAVAILABLE_RETRY_MAX) {
644 mHardwareFingerprintUnavailableRetryCount++;
Kevin Chyn0c45b072017-04-24 16:27:11 -0700645 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
646 mHandler.postDelayed(mRetryFingerprintAuthentication, HW_UNAVAILABLE_TIMEOUT);
647 }
648 }
649
Kevin Chyndf9d33e2017-05-03 21:40:12 -0700650 if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
651 mLockPatternUtils.requireStrongAuth(
652 LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
653 getCurrentUser());
654 }
655
Jim Miller9f0753f2015-03-23 23:59:22 -0700656 for (int i = 0; i < mCallbacks.size(); i++) {
657 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
658 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200659 cb.onBiometricError(msgId, errString, BiometricSourceType.FINGERPRINT);
Jim Millerf41fc962014-06-18 16:33:51 -0700660 }
661 }
662 }
663
Jorim Jaggi3a464782015-08-28 16:59:13 -0700664 private void handleFingerprintLockoutReset() {
665 updateFingerprintListeningState();
666 }
667
Jorim Jaggi86bed402015-08-20 18:20:02 -0700668 private void setFingerprintRunningState(int fingerprintRunningState) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200669 boolean wasRunning = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
670 boolean isRunning = fingerprintRunningState == BIOMETRIC_STATE_RUNNING;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700671 mFingerprintRunningState = fingerprintRunningState;
Kevin Chyn1123ba72018-10-26 10:34:06 -0700672 if (DEBUG) Log.v(TAG, "Fingerprint State: " + mFingerprintRunningState);
Jorim Jaggi86bed402015-08-20 18:20:02 -0700673 // Clients of KeyguardUpdateMonitor don't care about the internal state about the
674 // asynchronousness of the cancel cycle. So only notify them if the actualy running state
675 // has changed.
676 if (wasRunning != isRunning) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700677 notifyFingerprintRunningStateChanged();
678 }
679 }
680
681 private void notifyFingerprintRunningStateChanged() {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200682 checkIsHandlerThread();
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700683 for (int i = 0; i < mCallbacks.size(); i++) {
684 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
685 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200686 cb.onBiometricRunningStateChanged(isFingerprintDetectionRunning(),
687 BiometricSourceType.FINGERPRINT);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700688 }
689 }
690 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200691
Lucas Dupin3d053532019-01-29 12:35:22 -0800692 @VisibleForTesting
693 protected void onFaceAuthenticated(int userId) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200694 Trace.beginSection("KeyGuardUpdateMonitor#onFaceAuthenticated");
695 mUserFaceAuthenticated.put(userId, true);
696 // Update/refresh trust state only if user can skip bouncer
697 if (getUserCanSkipBouncer(userId)) {
698 mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FACE);
699 }
700 // Don't send cancel if authentication succeeds
701 mFaceCancelSignal = null;
702 for (int i = 0; i < mCallbacks.size(); i++) {
703 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
704 if (cb != null) {
705 cb.onBiometricAuthenticated(userId,
706 BiometricSourceType.FACE);
707 }
708 }
709
710 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE),
711 BIOMETRIC_CONTINUE_DELAY_MS);
712
713 // Only authenticate face once when assistant is visible
714 mAssistantVisible = false;
715
716 Trace.endSection();
717 }
718
719 private void handleFaceAuthFailed() {
Lucas Dupin38314812019-02-15 14:10:55 -0800720 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200721 for (int i = 0; i < mCallbacks.size(); i++) {
722 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
723 if (cb != null) {
724 cb.onBiometricAuthFailed(BiometricSourceType.FACE);
725 }
726 }
727 handleFaceHelp(-1, mContext.getString(R.string.kg_face_not_recognized));
728 }
729
730 private void handleFaceAcquired(int acquireInfo) {
731 if (acquireInfo != FaceManager.FACE_ACQUIRED_GOOD) {
732 return;
733 }
734 for (int i = 0; i < mCallbacks.size(); i++) {
735 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
736 if (cb != null) {
737 cb.onBiometricAcquired(BiometricSourceType.FACE);
738 }
739 }
740 }
741
742 private void handleFaceAuthenticated(int authUserId) {
743 Trace.beginSection("KeyGuardUpdateMonitor#handlerFaceAuthenticated");
744 try {
745 final int userId;
746 try {
747 userId = ActivityManager.getService().getCurrentUser().id;
748 } catch (RemoteException e) {
749 Log.e(TAG, "Failed to get current user id: ", e);
750 return;
751 }
752 if (userId != authUserId) {
753 Log.d(TAG, "Face authenticated for wrong user: " + authUserId);
754 return;
755 }
756 if (isFaceDisabled(userId)) {
757 Log.d(TAG, "Face authentication disabled by DPM for userId: " + userId);
758 return;
759 }
760 onFaceAuthenticated(userId);
761 } finally {
762 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
763 }
764 Trace.endSection();
765 }
766
767 private void handleFaceHelp(int msgId, String helpString) {
768 for (int i = 0; i < mCallbacks.size(); i++) {
769 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
770 if (cb != null) {
771 cb.onBiometricHelp(msgId, helpString, BiometricSourceType.FACE);
772 }
773 }
774 }
775
776 private Runnable mRetryFaceAuthentication = new Runnable() {
777 @Override
778 public void run() {
779 Log.w(TAG, "Retrying face after HW unavailable, attempt " +
780 mHardwareFaceUnavailableRetryCount);
781 updateFaceListeningState();
782 }
783 };
784
785 private void handleFaceError(int msgId, String errString) {
786 if (msgId == FaceManager.FACE_ERROR_CANCELED
787 && mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
788 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
Kevin Chyn1123ba72018-10-26 10:34:06 -0700789 updateFaceListeningState();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200790 } else {
791 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
792 }
793
794 if (msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE) {
795 if (mHardwareFaceUnavailableRetryCount < HW_UNAVAILABLE_RETRY_MAX) {
796 mHardwareFaceUnavailableRetryCount++;
797 mHandler.removeCallbacks(mRetryFaceAuthentication);
798 mHandler.postDelayed(mRetryFaceAuthentication, HW_UNAVAILABLE_TIMEOUT);
799 }
800 }
801
802 if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
803 mLockPatternUtils.requireStrongAuth(
804 LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
805 getCurrentUser());
806 }
807
808 for (int i = 0; i < mCallbacks.size(); i++) {
809 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
810 if (cb != null) {
811 cb.onBiometricError(msgId, errString,
812 BiometricSourceType.FACE);
813 }
814 }
815 }
816
817 private void handleFaceLockoutReset() {
818 updateFaceListeningState();
819 }
820
821 private void setFaceRunningState(int faceRunningState) {
822 boolean wasRunning = mFaceRunningState == BIOMETRIC_STATE_RUNNING;
823 boolean isRunning = faceRunningState == BIOMETRIC_STATE_RUNNING;
824 mFaceRunningState = faceRunningState;
Kevin Chyn1123ba72018-10-26 10:34:06 -0700825 if (DEBUG) Log.v(TAG, "Face State: " + mFaceRunningState);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200826 // Clients of KeyguardUpdateMonitor don't care about the internal state or about the
827 // asynchronousness of the cancel cycle. So only notify them if the actualy running state
828 // has changed.
829 if (wasRunning != isRunning) {
830 notifyFaceRunningStateChanged();
831 }
832 }
833
834 private void notifyFaceRunningStateChanged() {
835 for (int i = 0; i < mCallbacks.size(); i++) {
836 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
837 if (cb != null) {
838 cb.onBiometricRunningStateChanged(isFaceDetectionRunning(),
839 BiometricSourceType.FACE);
840 }
841 }
842 }
843
Adrian Roos4a410172014-08-20 17:41:44 +0200844 private void handleFaceUnlockStateChanged(boolean running, int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200845 checkIsHandlerThread();
Adrian Roos4a410172014-08-20 17:41:44 +0200846 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200847 for (int i = 0; i < mCallbacks.size(); i++) {
848 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
849 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200850 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200851 }
852 }
853 }
854
Adrian Roos4a410172014-08-20 17:41:44 +0200855 public boolean isFaceUnlockRunning(int userId) {
856 return mUserFaceUnlockRunning.get(userId);
857 }
858
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700859 public boolean isFingerprintDetectionRunning() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200860 return mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
861 }
862
863 public boolean isFaceDetectionRunning() {
864 return mFaceRunningState == BIOMETRIC_STATE_RUNNING;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700865 }
866
Jim Miller50e62182014-04-23 17:25:00 -0700867 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100868 // Don't allow trust agent if device is secured with a SIM PIN. This is here
869 // mainly because there's no other way to prompt the user to enter their SIM PIN
870 // once they get past the keyguard screen.
871 final boolean disabledBySimPin = isSimPinSecure();
872 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700873 }
874
Jim Miller06e34502014-07-17 14:46:05 -0700875 private boolean isFingerprintDisabled(int userId) {
876 final DevicePolicyManager dpm =
877 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
878 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
Adrian Roos733b6632015-08-21 14:32:35 -0700879 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0
880 || isSimPinSecure();
Jim Miller06e34502014-07-17 14:46:05 -0700881 }
882
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200883 private boolean isFaceDisabled(int userId) {
884 final DevicePolicyManager dpm =
885 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
886 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
887 & DevicePolicyManager.KEYGUARD_DISABLE_FACE) != 0
888 || isSimPinSecure();
889 }
890
891
Selim Cineke8bae622015-07-15 13:24:06 -0700892 public boolean getUserCanSkipBouncer(int userId) {
Lucas Dupin3d053532019-01-29 12:35:22 -0800893 boolean fingerprintOrFace = mUserFingerprintAuthenticated.get(userId)
894 || mUserFaceAuthenticated.get(userId);
895 return getUserHasTrust(userId) || (fingerprintOrFace && isUnlockingWithBiometricAllowed());
Selim Cineke8bae622015-07-15 13:24:06 -0700896 }
897
Adrian Roos46842d92014-03-27 14:58:03 +0100898 public boolean getUserHasTrust(int userId) {
Selim Cineke8bae622015-07-15 13:24:06 -0700899 return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100900 }
901
Adrian Roos7861c662014-07-25 15:37:28 +0200902 public boolean getUserTrustIsManaged(int userId) {
903 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
904 }
905
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200906 public boolean isUnlockingWithBiometricAllowed() {
907 return mStrongAuthTracker.isUnlockingWithBiometricAllowed();
Adrian Roosb5e47222015-08-14 15:53:06 -0700908 }
909
Lucas Dupin16013822018-05-17 18:00:16 -0700910 public boolean isUserInLockdown(int userId) {
911 return mStrongAuthTracker.getStrongAuthForUser(userId)
912 == LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
913 }
914
Jorim Jaggi031f7952016-09-01 16:39:26 -0700915 public boolean needsSlowUnlockTransition() {
916 return mNeedsSlowUnlockTransition;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700917 }
918
Adrian Roosb5e47222015-08-14 15:53:06 -0700919 public StrongAuthTracker getStrongAuthTracker() {
920 return mStrongAuthTracker;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700921 }
922
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700923 private void notifyStrongAuthStateChanged(int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200924 checkIsHandlerThread();
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700925 for (int i = 0; i < mCallbacks.size(); i++) {
926 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
927 if (cb != null) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700928 cb.onStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700929 }
930 }
Selim Cinek1fcafc42015-07-20 14:39:25 -0700931 }
932
Adrian Roos91ba3072017-02-14 16:50:46 +0100933 public boolean isScreenOn() {
934 return mScreenOn;
935 }
936
Lucas Dupinef886542018-01-03 16:03:07 -0800937 private void dispatchErrorMessage(CharSequence message) {
938 for (int i = 0; i < mCallbacks.size(); i++) {
939 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
940 if (cb != null) {
941 cb.onTrustAgentErrorMessage(message);
942 }
943 }
944 }
945
Lucas Dupin3d053532019-01-29 12:35:22 -0800946 @VisibleForTesting
947 void setAssistantVisible(boolean assistantVisible) {
948 mAssistantVisible = assistantVisible;
949 updateBiometricListeningState();
950 }
951
Jim Miller8f09fd22013-03-14 19:04:28 -0700952 static class DisplayClientState {
953 public int clientGeneration;
954 public boolean clearing;
955 public PendingIntent intent;
956 public int playbackState;
957 public long playbackEventTime;
958 }
959
960 private DisplayClientState mDisplayClientState = new DisplayClientState();
961
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800962 @VisibleForTesting
Lucas Dupin7ff82b02018-05-16 12:14:10 -0700963 protected final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
Jim Millerbbf1a742012-07-17 18:30:30 -0700964
Jim Millerd72d5ac2015-09-29 18:55:32 -0700965 @Override
Jim Millerbbf1a742012-07-17 18:30:30 -0700966 public void onReceive(Context context, Intent intent) {
967 final String action = intent.getAction();
968 if (DEBUG) Log.d(TAG, "received broadcast " + action);
969
970 if (Intent.ACTION_TIME_TICK.equals(action)
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500971 || Intent.ACTION_TIME_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700972 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500973 } else if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
974 final Message msg = mHandler.obtainMessage(
975 MSG_TIMEZONE_UPDATE, intent.getStringExtra("time-zone"));
976 mHandler.sendMessage(msg);
Jim Millerbbf1a742012-07-17 18:30:30 -0700977 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
978 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
979 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
980 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
981 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
Adrian Roos0c859ae2015-11-23 16:47:50 -0800982
983 final int maxChargingMicroAmp = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
984 int maxChargingMicroVolt = intent.getIntExtra(EXTRA_MAX_CHARGING_VOLTAGE, -1);
985 final int maxChargingMicroWatt;
986
987 if (maxChargingMicroVolt <= 0) {
988 maxChargingMicroVolt = DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT;
989 }
990 if (maxChargingMicroAmp > 0) {
991 // Calculating muW = muA * muV / (10^6 mu^2 / mu); splitting up the divisor
992 // to maintain precision equally on both factors.
993 maxChargingMicroWatt = (maxChargingMicroAmp / 1000)
994 * (maxChargingMicroVolt / 1000);
995 } else {
996 maxChargingMicroWatt = -1;
997 }
Jim Millerbbf1a742012-07-17 18:30:30 -0700998 final Message msg = mHandler.obtainMessage(
Adrian Roos7b043112015-07-10 13:00:33 -0700999 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
Adrian Roos0c859ae2015-11-23 16:47:50 -08001000 maxChargingMicroWatt));
Jim Millerbbf1a742012-07-17 18:30:30 -07001001 mHandler.sendMessage(msg);
1002 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Bill Linef81cbd2018-07-05 17:48:49 +08001003 SimData args = SimData.fromIntent(intent);
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001004 // ACTION_SIM_STATE_CHANGED is rebroadcast after unlocking the device to
1005 // keep compatibility with apps that aren't direct boot aware.
1006 // SysUI should just ignore this broadcast because it was already received
1007 // and processed previously.
1008 if (intent.getBooleanExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
Bill Linef81cbd2018-07-05 17:48:49 +08001009 // Guarantee mTelephonyCapable state after SysUI crash and restart
1010 if (args.simState == State.ABSENT) {
1011 mHandler.obtainMessage(MSG_TELEPHONY_CAPABLE, true).sendToTarget();
1012 }
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001013 return;
1014 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001015 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -08001016 Log.v(TAG, "action " + action
1017 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
1018 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -07001019 }
Jim Miller52a61332014-11-12 19:29:51 -08001020 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
1021 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -07001022 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
1023 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
1024 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
1025 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
1026 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
1027 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Jason Monk052082c2015-06-11 11:35:23 -04001028 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
1029 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001030 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -07001031 dispatchBootCompleted();
Etan Cohen47051d82015-07-06 16:19:04 -07001032 } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
1033 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
1034 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
1035 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
1036 if (DEBUG) {
1037 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
1038 + subId);
1039 }
1040 mHandler.sendMessage(
1041 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
Alex Chauff7653d2018-02-01 17:18:08 +00001042 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
1043 action)) {
1044 mHandler.sendEmptyMessage(MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001045 }
1046 }
1047 };
Jim Miller2de5ee82012-06-14 22:22:50 -07001048
Lucas Dupin3d053532019-01-29 12:35:22 -08001049 @VisibleForTesting
1050 protected final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001051
Jim Millerd72d5ac2015-09-29 18:55:32 -07001052 @Override
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001053 public void onReceive(Context context, Intent intent) {
1054 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +02001055 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
1056 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
1057 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001058 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
1059 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +02001060 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001061 Trace.beginSection("KeyguardUpdateMonitor.mBroadcastAllReceiver#onReceive ACTION_FACE_UNLOCK_STARTED");
Adrian Roos48c796c2014-09-01 14:59:23 +02001062 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
1063 getSendingUserId()));
Nick Desaulniers1d396752016-07-25 15:05:33 -07001064 Trace.endSection();
Adrian Roos48c796c2014-09-01 14:59:23 +02001065 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
1066 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
1067 getSendingUserId()));
1068 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
1069 .equals(action)) {
1070 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001071 } else if (ACTION_USER_UNLOCKED.equals(action)) {
1072 mHandler.sendEmptyMessage(MSG_USER_UNLOCKED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001073 }
1074 }
1075 };
Jim Miller9f0753f2015-03-23 23:59:22 -07001076
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001077 private final FingerprintManager.LockoutResetCallback mFingerprintLockoutResetCallback
Jorim Jaggi3a464782015-08-28 16:59:13 -07001078 = new FingerprintManager.LockoutResetCallback() {
1079 @Override
1080 public void onLockoutReset() {
1081 handleFingerprintLockoutReset();
1082 }
1083 };
1084
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001085 private final FaceManager.LockoutResetCallback mFaceLockoutResetCallback
1086 = new FaceManager.LockoutResetCallback() {
1087 @Override
1088 public void onLockoutReset() {
1089 handleFaceLockoutReset();
1090 }
1091 };
1092
1093 private FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback
Jim Miller9f0753f2015-03-23 23:59:22 -07001094 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -07001095
1096 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -07001097 public void onAuthenticationFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001098 handleFingerprintAuthFailed();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001099 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001100
1101 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -07001102 public void onAuthenticationSucceeded(AuthenticationResult result) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001103 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
Jim Miller837fa7e2016-08-08 20:16:22 -07001104 handleFingerprintAuthenticated(result.getUserId());
Nick Desaulniers1d396752016-07-25 15:05:33 -07001105 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -07001106 }
1107
1108 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -07001109 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001110 handleFingerprintHelp(helpMsgId, helpString.toString());
Jim Miller9f0753f2015-03-23 23:59:22 -07001111 }
1112
1113 @Override
1114 public void onAuthenticationError(int errMsgId, CharSequence errString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001115 handleFingerprintError(errMsgId, errString.toString());
1116 }
1117
1118 @Override
1119 public void onAuthenticationAcquired(int acquireInfo) {
1120 handleFingerprintAcquired(acquireInfo);
Jim Millerf41fc962014-06-18 16:33:51 -07001121 }
1122 };
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001123
Lucas Dupin3d053532019-01-29 12:35:22 -08001124 @VisibleForTesting
1125 FaceManager.AuthenticationCallback mFaceAuthenticationCallback
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001126 = new FaceManager.AuthenticationCallback() {
1127
1128 @Override
1129 public void onAuthenticationFailed() {
1130 handleFaceAuthFailed();
1131 }
1132
1133 @Override
1134 public void onAuthenticationSucceeded(FaceManager.AuthenticationResult result) {
1135 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
1136 handleFaceAuthenticated(result.getUserId());
1137 Trace.endSection();
1138 }
1139
1140 @Override
1141 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
1142 handleFaceHelp(helpMsgId, helpString.toString());
1143 }
1144
1145 @Override
1146 public void onAuthenticationError(int errMsgId, CharSequence errString) {
1147 handleFaceError(errMsgId, errString.toString());
1148 }
1149
1150 @Override
1151 public void onAuthenticationAcquired(int acquireInfo) {
1152 handleFaceAcquired(acquireInfo);
1153 }
1154 };
1155
Jim Miller9f0753f2015-03-23 23:59:22 -07001156 private CancellationSignal mFingerprintCancelSignal;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001157 private CancellationSignal mFaceCancelSignal;
Jim Miller9f0753f2015-03-23 23:59:22 -07001158 private FingerprintManager mFpm;
Kevin Chynb7b54a62018-09-28 18:48:12 -07001159 private FaceManager mFaceManager;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001160
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001161 /**
Jim Miller47088bb2009-11-24 00:40:16 -08001162 * When we receive a
1163 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -07001164 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001165 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -08001166 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001167 */
Jim Miller52a61332014-11-12 19:29:51 -08001168 private static class SimData {
1169 public State simState;
1170 public int slotId;
1171 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001172
Jim Miller52a61332014-11-12 19:29:51 -08001173 SimData(State state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -08001174 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -08001175 slotId = slot;
1176 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -08001177 }
1178
Jim Miller52a61332014-11-12 19:29:51 -08001179 static SimData fromIntent(Intent intent) {
1180 State state;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001181 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
1182 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
1183 }
Wink Savillea639b312012-07-10 12:37:54 -07001184 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
Jim Miller52a61332014-11-12 19:29:51 -08001185 int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0);
1186 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
Wink Savilled09c4ca2014-11-22 10:08:16 -08001187 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea639b312012-07-10 12:37:54 -07001188 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -07001189 final String absentReason = intent
Wink Savillea639b312012-07-10 12:37:54 -07001190 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -07001191
Wink Savillea639b312012-07-10 12:37:54 -07001192 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -07001193 absentReason)) {
Wink Savillea639b312012-07-10 12:37:54 -07001194 state = IccCardConstants.State.PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -07001195 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001196 state = IccCardConstants.State.ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -07001197 }
Wink Savillea639b312012-07-10 12:37:54 -07001198 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
1199 state = IccCardConstants.State.READY;
1200 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001201 final String lockedReason = intent
Wink Savillea639b312012-07-10 12:37:54 -07001202 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
1203 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
1204 state = IccCardConstants.State.PIN_REQUIRED;
1205 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
1206 state = IccCardConstants.State.PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001207 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001208 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001209 }
Wink Savillea639b312012-07-10 12:37:54 -07001210 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
1211 state = IccCardConstants.State.NETWORK_LOCKED;
Wileen Chiu6b8b22e2014-10-29 22:48:21 +05301212 } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
1213 state = IccCardConstants.State.CARD_IO_ERROR;
Jim Miller109f1fd2012-09-19 20:44:16 -07001214 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
1215 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
1216 // This is required because telephony doesn't return to "READY" after
1217 // these state transitions. See bug 7197471.
1218 state = IccCardConstants.State.READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001219 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001220 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001221 }
Jim Miller52a61332014-11-12 19:29:51 -08001222 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001223 }
1224
Jim Millerd72d5ac2015-09-29 18:55:32 -07001225 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001226 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -08001227 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001228 }
1229 }
1230
Adrian Roos12c1ef52014-06-04 13:54:08 +02001231 public static class BatteryStatus {
Adrian Roos7b043112015-07-10 13:00:33 -07001232 public static final int CHARGING_UNKNOWN = -1;
1233 public static final int CHARGING_SLOWLY = 0;
1234 public static final int CHARGING_REGULAR = 1;
1235 public static final int CHARGING_FAST = 2;
1236
Jim Miller16464b82011-10-20 21:10:13 -07001237 public final int status;
1238 public final int level;
1239 public final int plugged;
1240 public final int health;
Adrian Roos0c859ae2015-11-23 16:47:50 -08001241 public final int maxChargingWattage;
1242 public BatteryStatus(int status, int level, int plugged, int health,
1243 int maxChargingWattage) {
Jim Miller16464b82011-10-20 21:10:13 -07001244 this.status = status;
1245 this.level = level;
1246 this.plugged = plugged;
1247 this.health = health;
Adrian Roos0c859ae2015-11-23 16:47:50 -08001248 this.maxChargingWattage = maxChargingWattage;
Jim Miller16464b82011-10-20 21:10:13 -07001249 }
1250
Jim Millerbbf1a742012-07-17 18:30:30 -07001251 /**
Brian Muramatsua92a01b2012-09-05 21:54:39 -07001252 * Determine whether the device is plugged in (USB, power, or wireless).
Jim Millerbbf1a742012-07-17 18:30:30 -07001253 * @return true if the device is plugged in.
1254 */
Adrian Roosad3bc7f2014-10-30 18:29:38 +01001255 public boolean isPluggedIn() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001256 return plugged == BatteryManager.BATTERY_PLUGGED_AC
Brian Muramatsua92a01b2012-09-05 21:54:39 -07001257 || plugged == BatteryManager.BATTERY_PLUGGED_USB
1258 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Jim Millerbbf1a742012-07-17 18:30:30 -07001259 }
1260
1261 /**
Beverly2034c832018-03-19 11:18:51 -04001262 * Determine whether the device is plugged in (USB, power).
1263 * @return true if the device is plugged in wired (as opposed to wireless)
1264 */
1265 public boolean isPluggedInWired() {
1266 return plugged == BatteryManager.BATTERY_PLUGGED_AC
1267 || plugged == BatteryManager.BATTERY_PLUGGED_USB;
1268 }
1269
1270 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001271 * Whether or not the device is charged. Note that some devices never return 100% for
1272 * battery level, so this allows either battery level or status to determine if the
1273 * battery is charged.
1274 * @return true if the device is charged
1275 */
1276 public boolean isCharged() {
1277 return status == BATTERY_STATUS_FULL || level >= 100;
1278 }
1279
1280 /**
1281 * Whether battery is low and needs to be charged.
1282 * @return true if battery is low
1283 */
1284 public boolean isBatteryLow() {
1285 return level < LOW_BATTERY_THRESHOLD;
1286 }
1287
Adrian Roos7b043112015-07-10 13:00:33 -07001288 public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
Adrian Roos0c859ae2015-11-23 16:47:50 -08001289 return maxChargingWattage <= 0 ? CHARGING_UNKNOWN :
1290 maxChargingWattage < slowThreshold ? CHARGING_SLOWLY :
1291 maxChargingWattage > fastThreshold ? CHARGING_FAST :
Adrian Roos7b043112015-07-10 13:00:33 -07001292 CHARGING_REGULAR;
1293 }
Lucas Dupin3fcdd472018-01-19 19:06:45 -08001294
1295 @Override
1296 public String toString() {
1297 return "BatteryStatus{status=" + status + ",level=" + level + ",plugged=" + plugged
1298 + ",health=" + health + ",maxChargingWattage=" + maxChargingWattage + "}";
1299 }
Jim Miller16464b82011-10-20 21:10:13 -07001300 }
1301
Lucas Dupin3d053532019-01-29 12:35:22 -08001302 public static class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
1303 private final Consumer<Integer> mStrongAuthRequiredChangedCallback;
1304
1305 public StrongAuthTracker(Context context,
1306 Consumer<Integer> strongAuthRequiredChangedCallback) {
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001307 super(context);
Lucas Dupin3d053532019-01-29 12:35:22 -08001308 mStrongAuthRequiredChangedCallback = strongAuthRequiredChangedCallback;
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001309 }
Adrian Roosb5e47222015-08-14 15:53:06 -07001310
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001311 public boolean isUnlockingWithBiometricAllowed() {
Adrian Roosb5e47222015-08-14 15:53:06 -07001312 int userId = getCurrentUser();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001313 return isBiometricAllowedForUser(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -07001314 }
1315
1316 public boolean hasUserAuthenticatedSinceBoot() {
1317 int userId = getCurrentUser();
1318 return (getStrongAuthForUser(userId)
1319 & STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
1320 }
1321
1322 @Override
1323 public void onStrongAuthRequiredChanged(int userId) {
Lucas Dupin3d053532019-01-29 12:35:22 -08001324 mStrongAuthRequiredChangedCallback.accept(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -07001325 }
1326 }
1327
Jim Millerdcb3d842012-08-23 19:18:12 -07001328 public static KeyguardUpdateMonitor getInstance(Context context) {
1329 if (sInstance == null) {
1330 sInstance = new KeyguardUpdateMonitor(context);
1331 }
1332 return sInstance;
1333 }
1334
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001335 protected void handleStartedWakingUp() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001336 Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001337 updateBiometricListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001338 final int count = mCallbacks.size();
1339 for (int i = 0; i < count; i++) {
1340 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1341 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001342 cb.onStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -07001343 }
1344 }
Nick Desaulniers1d396752016-07-25 15:05:33 -07001345 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -07001346 }
1347
Jorim Jaggi95e40382015-09-16 15:53:42 -07001348 protected void handleStartedGoingToSleep(int arg1) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001349 clearBiometricRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -07001350 final int count = mCallbacks.size();
1351 for (int i = 0; i < count; i++) {
1352 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1353 if (cb != null) {
Jorim Jaggi95e40382015-09-16 15:53:42 -07001354 cb.onStartedGoingToSleep(arg1);
1355 }
1356 }
1357 mGoingToSleep = true;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001358 updateBiometricListeningState();
Jorim Jaggi95e40382015-09-16 15:53:42 -07001359 }
1360
1361 protected void handleFinishedGoingToSleep(int arg1) {
1362 mGoingToSleep = false;
1363 final int count = mCallbacks.size();
1364 for (int i = 0; i < count; i++) {
1365 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1366 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001367 cb.onFinishedGoingToSleep(arg1);
Jim Miller20daffd2013-10-07 14:59:53 -07001368 }
1369 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001370 updateBiometricListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001371 }
1372
Jorim Jaggif1518da2015-07-30 11:56:36 -07001373 private void handleScreenTurnedOn() {
1374 final int count = mCallbacks.size();
1375 for (int i = 0; i < count; i++) {
1376 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1377 if (cb != null) {
1378 cb.onScreenTurnedOn();
1379 }
1380 }
1381 }
1382
1383 private void handleScreenTurnedOff() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001384 mHardwareFingerprintUnavailableRetryCount = 0;
1385 mHardwareFaceUnavailableRetryCount = 0;
Jorim Jaggif1518da2015-07-30 11:56:36 -07001386 final int count = mCallbacks.size();
1387 for (int i = 0; i < count; i++) {
1388 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1389 if (cb != null) {
1390 cb.onScreenTurnedOff();
1391 }
1392 }
1393 }
1394
Selim Cinek99415392016-09-09 14:58:41 -07001395 private void handleDreamingStateChanged(int dreamStart) {
1396 final int count = mCallbacks.size();
Kevin Chyn36778ff2017-09-07 19:55:38 -07001397 mIsDreaming = dreamStart == 1;
Selim Cinek99415392016-09-09 14:58:41 -07001398 for (int i = 0; i < count; i++) {
1399 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1400 if (cb != null) {
Kevin Chyn36778ff2017-09-07 19:55:38 -07001401 cb.onDreamingStateChanged(mIsDreaming);
Selim Cinek99415392016-09-09 14:58:41 -07001402 }
1403 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001404 updateBiometricListeningState();
Selim Cinek99415392016-09-09 14:58:41 -07001405 }
1406
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001407 private void handleUserInfoChanged(int userId) {
1408 for (int i = 0; i < mCallbacks.size(); i++) {
1409 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1410 if (cb != null) {
1411 cb.onUserInfoChanged(userId);
1412 }
1413 }
1414 }
1415
Jorim Jaggidadafd42016-09-30 07:20:25 -07001416 private void handleUserUnlocked() {
1417 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1418 for (int i = 0; i < mCallbacks.size(); i++) {
1419 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1420 if (cb != null) {
1421 cb.onUserUnlocked();
1422 }
1423 }
1424 }
1425
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001426 @VisibleForTesting
1427 protected KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001428 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -08001429 mSubscriptionManager = SubscriptionManager.from(context);
Michael Jurkafff56142012-11-28 16:51:00 -08001430 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Lucas Dupin3d053532019-01-29 12:35:22 -08001431 mStrongAuthTracker = new StrongAuthTracker(context, this::notifyStrongAuthStateChanged);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001432
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001433 // Since device can't be un-provisioned, we only need to register a content observer
1434 // to update mDeviceProvisioned when we are...
1435 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001436 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001437 }
Jim Miller47088bb2009-11-24 00:40:16 -08001438
Jim Millerbbf1a742012-07-17 18:30:30 -07001439 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Adrian Roos7b043112015-07-10 13:00:33 -07001440 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001441
Jim Millerbbf1a742012-07-17 18:30:30 -07001442 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001443 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001444 filter.addAction(Intent.ACTION_TIME_TICK);
1445 filter.addAction(Intent.ACTION_TIME_CHANGED);
1446 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
1447 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Jason Monk052082c2015-06-11 11:35:23 -04001448 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001449 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Etan Cohen47051d82015-07-06 16:19:04 -07001450 filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -08001451 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -08001452 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Alex Chauff7653d2018-02-01 17:18:08 +00001453 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jason Monk7bb59302018-05-10 19:38:18 -07001454 context.registerReceiver(mBroadcastReceiver, filter, null, mHandler);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001455
Adam Cohenc276e822012-11-08 13:01:08 -08001456 final IntentFilter bootCompleteFilter = new IntentFilter();
1457 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1458 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
Jason Monk7bb59302018-05-10 19:38:18 -07001459 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter, null, mHandler);
Adam Cohenc276e822012-11-08 13:01:08 -08001460
Adrian Roos48c796c2014-09-01 14:59:23 +02001461 final IntentFilter allUserFilter = new IntentFilter();
1462 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
1463 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
1464 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
1465 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
1466 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001467 allUserFilter.addAction(ACTION_USER_UNLOCKED);
Adrian Roos48c796c2014-09-01 14:59:23 +02001468 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Jason Monk7bb59302018-05-10 19:38:18 -07001469 null, mHandler);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001470
Wink Saville071743f2015-01-12 17:11:04 -08001471 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001472 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001473 ActivityManager.getService().registerUserSwitchObserver(
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001474 new UserSwitchObserver() {
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001475 @Override
1476 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001477 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001478 newUserId, 0, reply));
1479 }
1480 @Override
1481 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001482 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +02001483 newUserId, 0));
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001484 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001485 }, TAG);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001486 } catch (RemoteException e) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001487 e.rethrowAsRuntimeException();
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001488 }
Adrian Roos46842d92014-03-27 14:58:03 +01001489
Jorim Jaggi237b0612015-05-01 14:28:49 -07001490 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
1491 mTrustManager.registerTrustListener(this);
Michal Karpinskic52f8672016-11-18 11:32:45 +00001492 mLockPatternUtils = new LockPatternUtils(context);
1493 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Jim Millerf41fc962014-06-18 16:33:51 -07001494
Kevin Chyn36778ff2017-09-07 19:55:38 -07001495 mDreamManager = IDreamManager.Stub.asInterface(
1496 ServiceManager.getService(DreamService.DREAM_SERVICE));
1497
Jorim Jaggi3f124262016-11-22 13:45:17 +01001498 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
1499 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
1500 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001501 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
Kevin Chynb7b54a62018-09-28 18:48:12 -07001502 mFaceManager = (FaceManager) context.getSystemService(Context.FACE_SERVICE);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001503 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07001504
1505 if (mFpm != null || mFaceManager != null) {
1506 mBiometricManager = context.getSystemService(BiometricManager.class);
1507 mBiometricManager.registerEnabledOnKeyguardCallback(mBiometricEnabledCallback);
1508 }
1509
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001510 updateBiometricListeningState();
Jorim Jaggi3a464782015-08-28 16:59:13 -07001511 if (mFpm != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001512 mFpm.addLockoutResetCallback(mFingerprintLockoutResetCallback);
1513 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07001514 if (mFaceManager != null) {
1515 mFaceManager.addLockoutResetCallback(mFaceLockoutResetCallback);
Jorim Jaggi3a464782015-08-28 16:59:13 -07001516 }
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001517
Winson Chung2cf6ad82017-11-09 17:36:59 -08001518 ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001519 mUserManager = context.getSystemService(UserManager.class);
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001520 mIsPrimaryUser = mUserManager.isPrimaryUser();
Alex Chauff7653d2018-02-01 17:18:08 +00001521 mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
1522 mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
Bill Linef81cbd2018-07-05 17:48:49 +08001523 updateAirplaneModeState();
1524 }
1525
1526 private void updateAirplaneModeState() {
1527 // ACTION_AIRPLANE_MODE_CHANGED do not broadcast if device set AirplaneMode ON and boot
1528 if (!WirelessUtils.isAirplaneModeOn(mContext)
1529 || mHandler.hasMessages(MSG_AIRPLANE_MODE_CHANGED)) {
1530 return;
1531 }
1532 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Jorim Jaggiea657062015-04-28 13:45:11 -07001533 }
1534
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001535 private void updateBiometricListeningState() {
1536 updateFingerprintListeningState();
1537 updateFaceListeningState();
1538 }
1539
Jorim Jaggiea657062015-04-28 13:45:11 -07001540 private void updateFingerprintListeningState() {
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001541 // If this message exists, we should not authenticate again until this message is
1542 // consumed by the handler
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001543 if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001544 return;
1545 }
Kevin Chyn0c45b072017-04-24 16:27:11 -07001546 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
Jorim Jaggiea657062015-04-28 13:45:11 -07001547 boolean shouldListenForFingerprint = shouldListenForFingerprint();
Adrian Roos2aaf9442018-11-20 16:57:33 +01001548 boolean runningOrRestarting = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING
1549 || mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING;
1550 if (runningOrRestarting && !shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001551 stopListeningForFingerprint();
Adrian Roos2aaf9442018-11-20 16:57:33 +01001552 } else if (!runningOrRestarting && shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001553 startListeningForFingerprint();
1554 }
1555 }
1556
Lucas Dupin3d053532019-01-29 12:35:22 -08001557 /**
Lucas Dupine0516d52019-02-05 17:54:06 -05001558 * Called whenever passive authentication is requested or aborted by a sensor.
1559 * @param active If the interrupt started or ended.
Lucas Dupin3d053532019-01-29 12:35:22 -08001560 */
Lucas Dupine0516d52019-02-05 17:54:06 -05001561 public void onAuthInterruptDetected(boolean active) {
1562 if (DEBUG) Log.d(TAG, "onAuthInterruptDetected(" + active + ")");
1563 if (mAuthInterruptActive == active) {
1564 return;
1565 }
1566 mAuthInterruptActive = active;
Lucas Dupin3d053532019-01-29 12:35:22 -08001567 updateFaceListeningState();
1568 }
1569
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001570 private void updateFaceListeningState() {
1571 // If this message exists, we should not authenticate again until this message is
1572 // consumed by the handler
1573 if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
1574 return;
1575 }
1576 mHandler.removeCallbacks(mRetryFaceAuthentication);
1577 boolean shouldListenForFace = shouldListenForFace();
1578 if (mFaceRunningState == BIOMETRIC_STATE_RUNNING && !shouldListenForFace) {
1579 stopListeningForFace();
1580 } else if (mFaceRunningState != BIOMETRIC_STATE_RUNNING
1581 && shouldListenForFace) {
1582 startListeningForFace();
1583 }
1584 }
1585
Kevin Chyn129f60f2017-08-11 17:24:42 -07001586 private boolean shouldListenForFingerprintAssistant() {
1587 return mAssistantVisible && mKeyguardOccluded
1588 && !mUserFingerprintAuthenticated.get(getCurrentUser(), false)
1589 && !mUserHasTrust.get(getCurrentUser(), false);
1590 }
1591
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001592 private boolean shouldListenForFaceAssistant() {
1593 return mAssistantVisible && mKeyguardOccluded
1594 && !mUserFaceAuthenticated.get(getCurrentUser(), false)
1595 && !mUserHasTrust.get(getCurrentUser(), false);
1596 }
1597
Jorim Jaggiea657062015-04-28 13:45:11 -07001598 private boolean shouldListenForFingerprint() {
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001599 // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
1600 // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
1601 final boolean shouldListen = (mKeyguardIsVisible || !mDeviceInteractive ||
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001602 (mBouncer && !mKeyguardGoingAway) || mGoingToSleep ||
Kevin Chyn36778ff2017-09-07 19:55:38 -07001603 shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming))
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001604 && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser())
Kevin Chyn225eea72019-03-06 16:42:00 -08001605 && (!mKeyguardGoingAway || !mDeviceInteractive) && mIsPrimaryUser;
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001606 return shouldListen;
Jim Miller9f0753f2015-03-23 23:59:22 -07001607 }
1608
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001609 private boolean shouldListenForFace() {
Lucas Dupin3d053532019-01-29 12:35:22 -08001610 final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep;
1611 final int user = getCurrentUser();
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001612 // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
1613 // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
Lucas Dupine0516d52019-02-05 17:54:06 -05001614 return (mBouncer || mAuthInterruptActive || awakeKeyguard || shouldListenForFaceAssistant())
Lucas Dupin3d053532019-01-29 12:35:22 -08001615 && !mSwitchingUser && !getUserCanSkipBouncer(user) && !isFaceDisabled(user)
Kevin Chyn0d9eccf2019-03-01 16:23:49 -08001616 && !mKeyguardGoingAway && mFaceSettingEnabledForUser
1617 && mUserManager.isUserUnlocked(user) && mIsPrimaryUser;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001618 }
1619
1620
Jim Millerce7eb6d2015-04-03 19:29:13 -07001621 private void startListeningForFingerprint() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001622 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING) {
1623 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001624 return;
1625 }
Adrian Roos2aaf9442018-11-20 16:57:33 +01001626 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1627 // Waiting for restart via handleFingerprintError().
1628 return;
1629 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001630 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -07001631 int userId = ActivityManager.getCurrentUser();
Jorim Jaggi71448a72015-08-18 19:49:04 -07001632 if (isUnlockWithFingerprintPossible(userId)) {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001633 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001634 mFingerprintCancelSignal.cancel();
1635 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001636 mFingerprintCancelSignal = new CancellationSignal();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001637 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mFingerprintAuthenticationCallback,
1638 null, userId);
1639 setFingerprintRunningState(BIOMETRIC_STATE_RUNNING);
1640 }
1641 }
1642
1643 private void startListeningForFace() {
1644 if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING) {
1645 setFaceRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);
1646 return;
1647 }
1648 if (DEBUG) Log.v(TAG, "startListeningForFace()");
1649 int userId = ActivityManager.getCurrentUser();
1650 if (isUnlockWithFacePossible(userId)) {
1651 if (mFaceCancelSignal != null) {
1652 mFaceCancelSignal.cancel();
1653 }
1654 mFaceCancelSignal = new CancellationSignal();
Kevin Chynb7b54a62018-09-28 18:48:12 -07001655 mFaceManager.authenticate(null, mFaceCancelSignal, 0,
Kevin Chyna56dff72018-06-19 18:41:12 -07001656 mFaceAuthenticationCallback, null);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001657 setFaceRunningState(BIOMETRIC_STATE_RUNNING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001658 }
1659 }
1660
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001661 public boolean isUnlockWithFingerprintPossible(int userId) {
Selim Cinek3122fa82015-06-18 01:38:59 -07001662 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
1663 && mFpm.getEnrolledFingerprints(userId).size() > 0;
1664 }
1665
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001666 public boolean isUnlockWithFacePossible(int userId) {
Kevin Chynb7b54a62018-09-28 18:48:12 -07001667 return mFaceManager != null && mFaceManager.isHardwareDetected()
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001668 && !isFaceDisabled(userId)
Kevin Chynb7b54a62018-09-28 18:48:12 -07001669 && mFaceManager.hasEnrolledTemplates(userId);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001670 }
1671
Jorim Jaggiea657062015-04-28 13:45:11 -07001672 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001673 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001674 if (mFingerprintRunningState == BIOMETRIC_STATE_RUNNING) {
Kevin Chyn2fefd462017-04-28 12:18:19 -07001675 if (mFingerprintCancelSignal != null) {
1676 mFingerprintCancelSignal.cancel();
1677 mFingerprintCancelSignal = null;
1678 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001679 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001680 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001681 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1682 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING);
1683 }
1684 }
1685
1686 private void stopListeningForFace() {
1687 if (DEBUG) Log.v(TAG, "stopListeningForFace()");
1688 if (mFaceRunningState == BIOMETRIC_STATE_RUNNING) {
1689 if (mFaceCancelSignal != null) {
1690 mFaceCancelSignal.cancel();
1691 mFaceCancelSignal = null;
1692 }
1693 setFaceRunningState(BIOMETRIC_STATE_CANCELLING);
1694 }
1695 if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1696 setFaceRunningState(BIOMETRIC_STATE_CANCELLING);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001697 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001698 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001699
Michael Jurkafff56142012-11-28 16:51:00 -08001700 private boolean isDeviceProvisionedInSettingsDb() {
1701 return Settings.Global.getInt(mContext.getContentResolver(),
1702 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1703 }
1704
Jim Millerbbf1a742012-07-17 18:30:30 -07001705 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -08001706 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001707 @Override
1708 public void onChange(boolean selfChange) {
1709 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -08001710 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001711 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001712 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001713 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001714 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001715 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001716 };
1717
1718 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -07001719 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -08001720 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -07001721
1722 // prevent a race condition between where we check the flag and where we register the
1723 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -08001724 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001725 if (provisioned != mDeviceProvisioned) {
1726 mDeviceProvisioned = provisioned;
1727 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001728 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001729 }
1730 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001731 }
1732
Jim Millerbbf1a742012-07-17 18:30:30 -07001733 /**
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001734 * Update the state whether Keyguard currently has a lockscreen wallpaper.
1735 *
1736 * @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper.
1737 */
1738 public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001739 checkIsHandlerThread();
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001740 if (hasLockscreenWallpaper != mHasLockscreenWallpaper) {
1741 mHasLockscreenWallpaper = hasLockscreenWallpaper;
1742 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1743 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1744 if (cb != null) {
1745 cb.onHasLockscreenWallpaperChanged(hasLockscreenWallpaper);
1746 }
1747 }
1748 }
1749 }
1750
1751 /**
1752 * @return Whether Keyguard has a lockscreen wallpaper.
1753 */
1754 public boolean hasLockscreenWallpaper() {
1755 return mHasLockscreenWallpaper;
1756 }
1757
1758 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001759 * Handle {@link #MSG_DPM_STATE_CHANGED}
1760 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001761 private void handleDevicePolicyManagerStateChanged() {
Adrian Roos733b6632015-08-21 14:32:35 -07001762 updateFingerprintListeningState();
Jim Millerdcb3d842012-08-23 19:18:12 -07001763 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1764 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1765 if (cb != null) {
1766 cb.onDevicePolicyManagerStateChanged();
1767 }
Jim Millerb0304762012-03-13 20:01:25 -07001768 }
1769 }
1770
Jim Millerbbf1a742012-07-17 18:30:30 -07001771 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001772 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -07001773 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001774 private void handleUserSwitching(int userId, IRemoteCallback reply) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001775 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001776 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1777 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001778 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -07001779 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001780 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001781 try {
1782 reply.sendResult(null);
1783 } catch (RemoteException e) {
1784 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001785 }
1786
Jim Millerbbf1a742012-07-17 18:30:30 -07001787 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001788 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
1789 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001790 private void handleUserSwitchComplete(int userId) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001791 for (int i = 0; i < mCallbacks.size(); i++) {
1792 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1793 if (cb != null) {
1794 cb.onUserSwitchComplete(userId);
1795 }
1796 }
1797 }
1798
1799 /**
Jim Miller90873d52013-09-26 18:11:38 -07001800 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
1801 * keyguard crashes sometime after boot, then it will never receive this
1802 * broadcast and hence not handle the event. This method is ultimately called by
1803 * PhoneWindowManager in this case.
1804 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001805 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001806 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -07001807 }
1808
1809 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001810 * Handle {@link #MSG_BOOT_COMPLETED}
1811 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001812 private void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001813 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001814 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001815 for (int i = 0; i < mCallbacks.size(); i++) {
1816 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1817 if (cb != null) {
1818 cb.onBootCompleted();
1819 }
1820 }
1821 }
1822
1823 /**
Jim Miller5ecd8112013-01-09 18:50:26 -08001824 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001825 * destroyed.
1826 */
1827 public boolean hasBootCompleted() {
1828 return mBootCompleted;
1829 }
1830
1831 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001832 * Handle {@link #MSG_DEVICE_PROVISIONED}
1833 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001834 private void handleDeviceProvisioned() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001835 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001836 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1837 if (cb != null) {
1838 cb.onDeviceProvisioned();
1839 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001840 }
Michael Jurkafff56142012-11-28 16:51:00 -08001841 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001842 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -08001843 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
1844 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001845 }
1846 }
1847
Jim Millerbbf1a742012-07-17 18:30:30 -07001848 /**
1849 * Handle {@link #MSG_PHONE_STATE_CHANGED}
1850 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001851 private void handlePhoneStateChanged(String newState) {
Jim Millerc23024d2010-02-24 15:37:00 -08001852 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001853 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
1854 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
1855 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
1856 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
1857 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
1858 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
1859 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001860 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001861 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1862 if (cb != null) {
1863 cb.onPhoneStateChanged(mPhoneState);
1864 }
Jim Millerc23024d2010-02-24 15:37:00 -08001865 }
1866 }
1867
Jim Millerbbf1a742012-07-17 18:30:30 -07001868 /**
1869 * Handle {@link #MSG_RINGER_MODE_CHANGED}
1870 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001871 private void handleRingerModeChange(int mode) {
Jim Miller47088bb2009-11-24 00:40:16 -08001872 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001873 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -07001874 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001875 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1876 if (cb != null) {
1877 cb.onRingerModeChanged(mode);
1878 }
Jim Miller47088bb2009-11-24 00:40:16 -08001879 }
1880 }
1881
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001882 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001883 * Handle {@link #MSG_TIME_UPDATE}
1884 */
1885 private void handleTimeUpdate() {
1886 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001887 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001888 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1889 if (cb != null) {
1890 cb.onTimeChanged();
1891 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001892 }
1893 }
1894
1895 /**
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05001896 * Handle (@line #MSG_TIMEZONE_UPDATE}
1897 */
1898 private void handleTimeZoneUpdate(String timeZone) {
1899 if (DEBUG) Log.d(TAG, "handleTimeZoneUpdate");
1900 for (int i = 0; i < mCallbacks.size(); i++) {
1901 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1902 if (cb != null) {
1903 cb.onTimeZoneChanged(TimeZone.getTimeZone(timeZone));
1904 // Also notify callbacks about time change to remain compatible.
1905 cb.onTimeChanged();
1906 }
1907 }
1908 }
1909
1910 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001911 * Handle {@link #MSG_BATTERY_UPDATE}
1912 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001913 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001914 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001915 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
1916 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07001917 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001918 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001919 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1920 if (cb != null) {
1921 cb.onRefreshBatteryInfo(status);
1922 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001923 }
1924 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001925 }
1926
1927 /**
Bill Linef81cbd2018-07-05 17:48:49 +08001928 * Handle Telephony status during Boot for CarrierText display policy
1929 */
1930 @VisibleForTesting
1931 void updateTelephonyCapable(boolean capable){
1932 if (capable == mTelephonyCapable) {
1933 return;
1934 }
1935 mTelephonyCapable = capable;
1936 for (WeakReference<KeyguardUpdateMonitorCallback> ref : mCallbacks) {
1937 KeyguardUpdateMonitorCallback cb = ref.get();
1938 if (cb != null) {
1939 cb.onTelephonyCapable(mTelephonyCapable);
1940 }
1941 }
1942 }
1943
1944 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001945 * Handle {@link #MSG_SIM_STATE_CHANGE}
1946 */
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001947 @VisibleForTesting
Adrian Roos30a2ae62018-04-25 19:09:50 +02001948 void handleSimStateChange(int subId, int slotId, State state) {
1949 checkIsHandlerThread();
Jim Miller52a61332014-11-12 19:29:51 -08001950 if (DEBUG_SIM_STATES) {
1951 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
1952 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001953 }
1954
Lucas Dupin2e0d4952018-12-05 20:03:53 -08001955 boolean becameAbsent = false;
Wink Savillea54bf652014-12-11 13:37:50 -08001956 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08001957 Log.w(TAG, "invalid subId in handleSimStateChange()");
Bill Linef81cbd2018-07-05 17:48:49 +08001958 /* Only handle No SIM(ABSENT) due to handleServiceStateChange() handle other case */
1959 if (state == State.ABSENT) {
1960 updateTelephonyCapable(true);
Lucas Dupin2e0d4952018-12-05 20:03:53 -08001961 // Even though the subscription is not valid anymore, we need to notify that the
1962 // SIM card was removed so we can update the UI.
1963 becameAbsent = true;
Brad Ebingere6c6f722018-12-20 21:11:44 -08001964 for (SimData data : mSimDatas.values()) {
1965 // Set the SIM state of all SimData associated with that slot to ABSENT se we
1966 // do not move back into PIN/PUK locked and not detect the change below.
1967 if (data.slotId == slotId) {
1968 data.simState = State.ABSENT;
1969 }
1970 }
Lucas Dupin2e0d4952018-12-05 20:03:53 -08001971 } else {
1972 return;
Bill Linef81cbd2018-07-05 17:48:49 +08001973 }
Jim Miller52a61332014-11-12 19:29:51 -08001974 }
1975
1976 SimData data = mSimDatas.get(subId);
1977 final boolean changed;
1978 if (data == null) {
1979 data = new SimData(state, slotId, subId);
1980 mSimDatas.put(subId, data);
1981 changed = true; // no data yet; force update
1982 } else {
1983 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
1984 data.simState = state;
1985 data.subId = subId;
1986 data.slotId = slotId;
1987 }
Lucas Dupin2e0d4952018-12-05 20:03:53 -08001988 if ((changed || becameAbsent) && state != State.UNKNOWN) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001989 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001990 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1991 if (cb != null) {
Jim Miller52a61332014-11-12 19:29:51 -08001992 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07001993 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001994 }
1995 }
1996 }
1997
Jim Millerbbf1a742012-07-17 18:30:30 -07001998 /**
Etan Cohen47051d82015-07-06 16:19:04 -07001999 * Handle {@link #MSG_SERVICE_STATE_CHANGE}
2000 */
Bill Linef81cbd2018-07-05 17:48:49 +08002001 @VisibleForTesting
2002 void handleServiceStateChange(int subId, ServiceState serviceState) {
Etan Cohen47051d82015-07-06 16:19:04 -07002003 if (DEBUG) {
2004 Log.d(TAG,
2005 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
2006 }
2007
2008 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2009 Log.w(TAG, "invalid subId in handleServiceStateChange()");
2010 return;
Bill Linef81cbd2018-07-05 17:48:49 +08002011 } else {
2012 updateTelephonyCapable(true);
Etan Cohen47051d82015-07-06 16:19:04 -07002013 }
2014
2015 mServiceStates.put(subId, serviceState);
2016
2017 for (int j = 0; j < mCallbacks.size(); j++) {
2018 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
2019 if (cb != null) {
2020 cb.onRefreshCarrierInfo();
2021 }
2022 }
2023 }
2024
Lucas Dupinf8463ee2018-06-11 16:18:15 -07002025 public boolean isKeyguardVisible() {
2026 return mKeyguardIsVisible;
2027 }
2028
Etan Cohen47051d82015-07-06 16:19:04 -07002029 /**
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002030 * Notifies that the visibility state of Keyguard has changed.
2031 *
2032 * <p>Needs to be called from the main thread.
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002033 */
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002034 public void onKeyguardVisibilityChanged(boolean showing) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002035 checkIsHandlerThread();
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002036 if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
2037 mKeyguardIsVisible = showing;
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002038 for (int i = 0; i < mCallbacks.size(); i++) {
2039 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2040 if (cb != null) {
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002041 cb.onKeyguardVisibilityChangedRaw(showing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002042 }
2043 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002044 updateBiometricListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002045 }
2046
Brian Colonna7fce3802013-09-17 15:51:32 -04002047 /**
Selim Cinek1fcafc42015-07-20 14:39:25 -07002048 * Handle {@link #MSG_KEYGUARD_RESET}
2049 */
2050 private void handleKeyguardReset() {
2051 if (DEBUG) Log.d(TAG, "handleKeyguardReset");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002052 updateBiometricListeningState();
Jorim Jaggi031f7952016-09-01 16:39:26 -07002053 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
2054 }
2055
2056 private boolean resolveNeedsSlowUnlockTransition() {
2057 if (mUserManager.isUserUnlocked(getCurrentUser())) {
2058 return false;
2059 }
2060 Intent homeIntent = new Intent(Intent.ACTION_MAIN)
2061 .addCategory(Intent.CATEGORY_HOME);
2062 ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(homeIntent,
2063 0 /* flags */);
2064 return FALLBACK_HOME_COMPONENT.equals(resolveInfo.getComponentInfo().getComponentName());
Selim Cinek1fcafc42015-07-20 14:39:25 -07002065 }
2066
2067 /**
Adrian Roosb6011622014-05-14 15:52:53 +02002068 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
2069 * @see #sendKeyguardBouncerChanged(boolean)
2070 */
2071 private void handleKeyguardBouncerChanged(int bouncer) {
2072 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
2073 boolean isBouncer = (bouncer == 1);
2074 mBouncer = isBouncer;
2075 for (int i = 0; i < mCallbacks.size(); i++) {
2076 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2077 if (cb != null) {
2078 cb.onKeyguardBouncerChanged(isBouncer);
2079 }
2080 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002081 updateBiometricListeningState();
Adrian Roosb6011622014-05-14 15:52:53 +02002082 }
2083
2084 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04002085 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
2086 */
2087 private void handleReportEmergencyCallAction() {
2088 for (int i = 0; i < mCallbacks.size(); i++) {
2089 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2090 if (cb != null) {
2091 cb.onEmergencyCallAction();
2092 }
2093 }
2094 }
2095
Lucas Dupin4272f442018-01-13 22:00:35 -08002096 private boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002097 final boolean nowPluggedIn = current.isPluggedIn();
2098 final boolean wasPluggedIn = old.isPluggedIn();
Lucas Dupin4272f442018-01-13 22:00:35 -08002099 final boolean stateChangedWhilePluggedIn = wasPluggedIn && nowPluggedIn
Jim Miller16464b82011-10-20 21:10:13 -07002100 && (old.status != current.status);
2101
2102 // change in plug state is always interesting
2103 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002104 return true;
2105 }
2106
Lucas Dupin3fcdd472018-01-19 19:06:45 -08002107 // change in battery level
2108 if (old.level != current.level) {
Jim Miller16464b82011-10-20 21:10:13 -07002109 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002110 }
Adrian Roos76dc5a52015-07-21 16:20:36 -07002111
2112 // change in charging current while plugged in
Adrian Roos0c859ae2015-11-23 16:47:50 -08002113 if (nowPluggedIn && current.maxChargingWattage != old.maxChargingWattage) {
Adrian Roos76dc5a52015-07-21 16:20:36 -07002114 return true;
2115 }
2116
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002117 return false;
2118 }
2119
2120 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07002121 * Remove the given observer's callback.
2122 *
Jim Miller6212cc02012-09-05 17:35:31 -07002123 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002124 */
Jim Miller6212cc02012-09-05 17:35:31 -07002125 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002126 checkIsHandlerThread();
Jim Miller6212cc02012-09-05 17:35:31 -07002127 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
2128 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
2129 if (mCallbacks.get(i).get() == callback) {
2130 mCallbacks.remove(i);
2131 }
2132 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002133 }
2134
2135 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002136 * Register to receive notifications about general keyguard information
2137 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07002138 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002139 */
Jim Millerbbf1a742012-07-17 18:30:30 -07002140 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002141 checkIsHandlerThread();
Jim Miller6212cc02012-09-05 17:35:31 -07002142 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
2143 // Prevent adding duplicate callbacks
2144 for (int i = 0; i < mCallbacks.size(); i++) {
2145 if (mCallbacks.get(i).get() == callback) {
2146 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
2147 new Exception("Called by"));
2148 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07002149 }
2150 }
Jim Miller6212cc02012-09-05 17:35:31 -07002151 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
2152 removeCallback(null); // remove unused references
2153 sendUpdates(callback);
2154 }
2155
Evan Rosky18396452016-07-27 15:19:37 -07002156 public boolean isSwitchingUser() {
2157 return mSwitchingUser;
2158 }
2159
Adrian Roos30a2ae62018-04-25 19:09:50 +02002160 @AnyThread
Evan Rosky18396452016-07-27 15:19:37 -07002161 public void setSwitchingUser(boolean switching) {
2162 mSwitchingUser = switching;
Selim Cinekbbe19242017-12-08 15:42:08 -08002163 // Since this comes in on a binder thread, we need to post if first
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002164 mHandler.post(mUpdateBiometricListeningState);
Evan Rosky18396452016-07-27 15:19:37 -07002165 }
2166
Jim Miller6212cc02012-09-05 17:35:31 -07002167 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
2168 // Notify listener of the current state
2169 callback.onRefreshBatteryInfo(mBatteryStatus);
2170 callback.onTimeChanged();
2171 callback.onRingerModeChanged(mRingMode);
2172 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05002173 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07002174 callback.onClockVisibilityChanged();
Lucas Dupin16cfe452018-02-08 13:14:50 -08002175 callback.onKeyguardVisibilityChangedRaw(mKeyguardIsVisible);
Bill Linef81cbd2018-07-05 17:48:49 +08002176 callback.onTelephonyCapable(mTelephonyCapable);
Jim Miller52a61332014-11-12 19:29:51 -08002177 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
2178 final SimData state = data.getValue();
2179 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
2180 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002181 }
2182
Selim Cinek1fcafc42015-07-20 14:39:25 -07002183 public void sendKeyguardReset() {
2184 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
2185 }
2186
Adrian Roosb6011622014-05-14 15:52:53 +02002187 /**
2188 * @see #handleKeyguardBouncerChanged(int)
2189 */
2190 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
2191 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
2192 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
2193 message.arg1 = showingBouncer ? 1 : 0;
2194 message.sendToTarget();
2195 }
2196
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002197 /**
Jim Miller90d5d462011-11-17 16:57:01 -08002198 * 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 -08002199 * have the information earlier than waiting for the intent
2200 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08002201 *
2202 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
2203 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002204 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02002205 @MainThread
Jim Miller52a61332014-11-12 19:29:51 -08002206 public void reportSimUnlocked(int subId) {
2207 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
Sanket Padawe7e460252017-03-10 16:18:20 -08002208 int slotId = SubscriptionManager.getSlotIndex(subId);
Jim Miller52a61332014-11-12 19:29:51 -08002209 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002210 }
2211
Brian Colonna7fce3802013-09-17 15:51:32 -04002212 /**
2213 * Report that the emergency call button has been pressed and the emergency dialer is
2214 * about to be displayed.
2215 *
2216 * @param bypassHandler runs immediately.
2217 *
2218 * NOTE: Must be called from UI thread if bypassHandler == true.
2219 */
2220 public void reportEmergencyCallAction(boolean bypassHandler) {
2221 if (!bypassHandler) {
2222 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
2223 } else {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002224 checkIsHandlerThread();
Brian Colonna7fce3802013-09-17 15:51:32 -04002225 handleReportEmergencyCallAction();
2226 }
2227 }
2228
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002229 /**
2230 * @return Whether the device is provisioned (whether they have gone through
2231 * the setup wizard)
2232 */
2233 public boolean isDeviceProvisioned() {
2234 return mDeviceProvisioned;
2235 }
2236
Kensuke Matsui21d1bf12017-03-14 13:27:20 +09002237 public ServiceState getServiceState(int subId) {
2238 return mServiceStates.get(subId);
2239 }
2240
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002241 public void clearBiometricRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07002242 mUserFingerprintAuthenticated.clear();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002243 mUserFaceAuthenticated.clear();
2244 mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FINGERPRINT);
2245 mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FACE);
Jim Millerf41fc962014-06-18 16:33:51 -07002246 }
2247
Jim Miller52a61332014-11-12 19:29:51 -08002248 public boolean isSimPinVoiceSecure() {
2249 // TODO: only count SIMs that handle voice
2250 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07002251 }
2252
2253 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08002254 // True if any SIM is pin secure
2255 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
2256 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
2257 }
2258 return false;
2259 }
2260
Jason Monk9ff69bd2014-12-02 16:43:17 -05002261 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08002262 if (mSimDatas.containsKey(subId)) {
2263 return mSimDatas.get(subId).simState;
2264 } else {
2265 return State.UNKNOWN;
2266 }
2267 }
2268
Winson Chung67f5c8b2018-09-24 12:09:19 -07002269 private final TaskStackChangeListener
2270 mTaskStackListener = new TaskStackChangeListener() {
Kevin Chyn2fefd462017-04-28 12:18:19 -07002271 @Override
2272 public void onTaskStackChangedBackground() {
2273 try {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002274 ActivityManager.StackInfo info = ActivityTaskManager.getService().getStackInfo(
Wale Ogunwale68278562017-09-23 17:13:55 -07002275 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
Kevin Chyn2fefd462017-04-28 12:18:19 -07002276 if (info == null) {
2277 return;
2278 }
2279 mHandler.sendMessage(mHandler.obtainMessage(MSG_ASSISTANT_STACK_CHANGED,
2280 info.visible));
2281 } catch (RemoteException e) {
2282 Log.e(TAG, "unable to check task stack", e);
2283 }
2284 }
2285 };
2286
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002287 /**
Richard Choue0381b82018-04-24 03:48:59 +00002288 * @return true if and only if the state has changed for the specified {@code slotId}
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002289 */
Richard Choue0381b82018-04-24 03:48:59 +00002290 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08002291
2292 // This is awful. It exists because there are two APIs for getting the SIM status
2293 // that don't return the complete set of values and have different types. In Keyguard we
2294 // need IccCardConstants, but TelephonyManager would only give us
2295 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08002296 final TelephonyManager tele = TelephonyManager.from(mContext);
Richard Choue0381b82018-04-24 03:48:59 +00002297 int simState = tele.getSimState(slotId);
2298 State state;
2299 try {
2300 state = State.intToState(simState);
2301 } catch(IllegalArgumentException ex) {
2302 Log.w(TAG, "Unknown sim state: " + simState);
2303 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05002304 }
Richard Choue0381b82018-04-24 03:48:59 +00002305 SimData data = mSimDatas.get(subId);
2306 final boolean changed;
2307 if (data == null) {
2308 data = new SimData(state, slotId, subId);
2309 mSimDatas.put(subId, data);
2310 changed = true; // no data yet; force update
2311 } else {
2312 changed = data.simState != state;
2313 data.simState = state;
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002314 }
Richard Choue0381b82018-04-24 03:48:59 +00002315 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07002316 }
2317
2318 public static boolean isSimPinSecure(IccCardConstants.State state) {
2319 final IccCardConstants.State simState = state;
2320 return (simState == IccCardConstants.State.PIN_REQUIRED
2321 || simState == IccCardConstants.State.PUK_REQUIRED
2322 || simState == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07002323 }
Jim Miller8f09fd22013-03-14 19:04:28 -07002324
2325 public DisplayClientState getCachedDisplayClientState() {
2326 return mDisplayClientState;
2327 }
Jim Miller20daffd2013-10-07 14:59:53 -07002328
2329 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
2330 // (KeyguardViewMediator, KeyguardHostView)
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002331 public void dispatchStartedWakingUp() {
2332 synchronized (this) {
2333 mDeviceInteractive = true;
2334 }
2335 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
2336 }
2337
Jorim Jaggi95e40382015-09-16 15:53:42 -07002338 public void dispatchStartedGoingToSleep(int why) {
2339 mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
2340 }
2341
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002342 public void dispatchFinishedGoingToSleep(int why) {
2343 synchronized(this) {
2344 mDeviceInteractive = false;
2345 }
2346 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
2347 }
2348
Jim Miller20daffd2013-10-07 14:59:53 -07002349 public void dispatchScreenTurnedOn() {
2350 synchronized (this) {
2351 mScreenOn = true;
2352 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07002353 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
Jim Miller20daffd2013-10-07 14:59:53 -07002354 }
2355
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002356 public void dispatchScreenTurnedOff() {
Jim Miller20daffd2013-10-07 14:59:53 -07002357 synchronized(this) {
2358 mScreenOn = false;
2359 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07002360 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
Jim Miller20daffd2013-10-07 14:59:53 -07002361 }
2362
Selim Cinek99415392016-09-09 14:58:41 -07002363 public void dispatchDreamingStarted() {
2364 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 1, 0));
2365 }
2366
2367 public void dispatchDreamingStopped() {
2368 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 0, 0));
2369 }
2370
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002371 public boolean isDeviceInteractive() {
2372 return mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -07002373 }
Jim Miller52a61332014-11-12 19:29:51 -08002374
Jorim Jaggi95e40382015-09-16 15:53:42 -07002375 public boolean isGoingToSleep() {
2376 return mGoingToSleep;
2377 }
2378
Jim Miller52a61332014-11-12 19:29:51 -08002379 /**
2380 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
2381 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08002382 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08002383 */
2384 public int getNextSubIdForState(State state) {
2385 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08002386 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08002387 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
2388 for (int i = 0; i < list.size(); i++) {
2389 final SubscriptionInfo info = list.get(i);
2390 final int id = info.getSubscriptionId();
Sanket Padawe7e460252017-03-10 16:18:20 -08002391 int slotId = SubscriptionManager.getSlotIndex(id);
Jim Miller52a61332014-11-12 19:29:51 -08002392 if (state == getSimState(id) && bestSlotId > slotId ) {
2393 resultId = id;
2394 bestSlotId = slotId;
2395 }
2396 }
2397 return resultId;
2398 }
2399
2400 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
2401 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
2402 for (int i = 0; i < list.size(); i++) {
2403 SubscriptionInfo info = list.get(i);
2404 if (subId == info.getSubscriptionId()) return info;
2405 }
2406 return null; // not found
2407 }
Jason Monkab525272015-07-13 17:02:49 -04002408
Alex Chauff7653d2018-02-01 17:18:08 +00002409 /**
2410 * @return a cached version of DevicePolicyManager.isLogoutEnabled()
2411 */
2412 public boolean isLogoutEnabled() {
2413 return mLogoutEnabled;
2414 }
2415
2416 private void updateLogoutEnabled() {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002417 checkIsHandlerThread();
Alex Chauff7653d2018-02-01 17:18:08 +00002418 boolean logoutEnabled = mDevicePolicyManager.isLogoutEnabled();
2419 if (mLogoutEnabled != logoutEnabled) {
2420 mLogoutEnabled = logoutEnabled;
2421 for (int i = 0; i < mCallbacks.size(); i++) {
2422 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2423 if (cb != null) {
2424 cb.onLogoutEnabledChanged();
2425 }
2426 }
2427 }
2428 }
2429
Adrian Roos30a2ae62018-04-25 19:09:50 +02002430 private void checkIsHandlerThread() {
2431 if (sDisableHandlerCheckForTesting) {
2432 return;
2433 }
2434 if (!mHandler.getLooper().isCurrentThread()) {
2435 Log.wtf(TAG, "must call on mHandler's thread "
2436 + mHandler.getLooper().getThread() + ", not " + Thread.currentThread());
2437 }
2438 }
2439
2440 /**
2441 * Turn off the handler check for testing.
2442 *
2443 * This is necessary because currently tests are not too careful about which thread they call
2444 * into this class on.
2445 *
2446 * Note that this must be called before scheduling any work involving KeyguardUpdateMonitor
2447 * instances.
2448 *
2449 * TODO: fix the tests and remove this.
2450 */
2451 @VisibleForTesting
2452 public static void disableHandlerCheckForTesting(Instrumentation instrumentation) {
2453 Preconditions.checkNotNull(instrumentation, "Must only call this method in tests!");
2454 // Don't need synchronization here *if* the callers follow the contract and call this only
2455 // before scheduling work for KeyguardUpdateMonitor on other threads, because the scheduling
2456 // of that work forces a happens-before relationship.
2457 sDisableHandlerCheckForTesting = true;
2458 }
2459
Jason Monkab525272015-07-13 17:02:49 -04002460 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2461 pw.println("KeyguardUpdateMonitor state:");
2462 pw.println(" SIM States:");
2463 for (SimData data : mSimDatas.values()) {
2464 pw.println(" " + data.toString());
2465 }
2466 pw.println(" Subs:");
2467 if (mSubscriptionInfo != null) {
2468 for (int i = 0; i < mSubscriptionInfo.size(); i++) {
2469 pw.println(" " + mSubscriptionInfo.get(i));
2470 }
2471 }
2472 pw.println(" Service states:");
2473 for (int subId : mServiceStates.keySet()) {
2474 pw.println(" " + subId + "=" + mServiceStates.get(subId));
2475 }
Jim Millerd72d5ac2015-09-29 18:55:32 -07002476 if (mFpm != null && mFpm.isHardwareDetected()) {
2477 final int userId = ActivityManager.getCurrentUser();
2478 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
2479 pw.println(" Fingerprint state (user=" + userId + ")");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002480 pw.println(" allowed=" + isUnlockingWithBiometricAllowed());
Jim Millerd72d5ac2015-09-29 18:55:32 -07002481 pw.println(" auth'd=" + mUserFingerprintAuthenticated.get(userId));
2482 pw.println(" authSinceBoot="
2483 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
2484 pw.println(" disabled(DPM)=" + isFingerprintDisabled(userId));
2485 pw.println(" possible=" + isUnlockWithFingerprintPossible(userId));
Adrian Roos2aaf9442018-11-20 16:57:33 +01002486 pw.println(" listening: actual=" + mFingerprintRunningState
2487 + " expected=" + (shouldListenForFingerprint() ? 1 : 0));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002488 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002489 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
2490 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07002491 if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002492 final int userId = ActivityManager.getCurrentUser();
2493 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
2494 pw.println(" Face authentication state (user=" + userId + ")");
2495 pw.println(" allowed=" + isUnlockingWithBiometricAllowed());
2496 pw.println(" auth'd=" + mUserFaceAuthenticated.get(userId));
2497 pw.println(" authSinceBoot="
2498 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
2499 pw.println(" disabled(DPM)=" + isFaceDisabled(userId));
2500 pw.println(" possible=" + isUnlockWithFacePossible(userId));
2501 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
2502 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
Kevin Chynb7b54a62018-09-28 18:48:12 -07002503 pw.println(" enabledByUser=" + mFaceSettingEnabledForUser);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002504 }
Jason Monkab525272015-07-13 17:02:49 -04002505 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002506}