blob: 3ac7fd4c61c1149b7fe10e0d2c2947bb4cd4f95d [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;
Jim Miller52a61332014-11-12 19:29:51 -0800199 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
Etan Cohen47051d82015-07-06 16:19:04 -0700200 HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700201
Jim Millerbbf1a742012-07-17 18:30:30 -0700202 private int mRingMode;
203 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400204 private boolean mKeyguardIsVisible;
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700205 private boolean mKeyguardGoingAway;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700206 private boolean mGoingToSleep;
Adrian Roosb6011622014-05-14 15:52:53 +0200207 private boolean mBouncer;
Lucas Dupine0516d52019-02-05 17:54:06 -0500208 private boolean mAuthInterruptActive;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800209 private boolean mBootCompleted;
Jorim Jaggi031f7952016-09-01 16:39:26 -0700210 private boolean mNeedsSlowUnlockTransition;
Jorim Jaggid11d1a92016-08-16 16:02:32 -0700211 private boolean mHasLockscreenWallpaper;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700212 private boolean mAssistantVisible;
213 private boolean mKeyguardOccluded;
Bill Linef81cbd2018-07-05 17:48:49 +0800214 @VisibleForTesting
215 protected boolean mTelephonyCapable;
Jim Millerbbf1a742012-07-17 18:30:30 -0700216
Jim Millerdcb3d842012-08-23 19:18:12 -0700217 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700218 private boolean mDeviceProvisioned;
219
Jim Millerdcb3d842012-08-23 19:18:12 -0700220 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700221 private BatteryStatus mBatteryStatus;
222
Lucas Dupin3d053532019-01-29 12:35:22 -0800223 @VisibleForTesting
224 protected StrongAuthTracker mStrongAuthTracker;
Jim Millerbbf1a742012-07-17 18:30:30 -0700225
Jim Miller6212cc02012-09-05 17:35:31 -0700226 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700227 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800228 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700229
Brian Colonnaa5239892013-04-15 11:45:40 -0400230 private boolean mSwitchingUser;
231
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700232 private boolean mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -0700233 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800234 private SubscriptionManager mSubscriptionManager;
235 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700236 private TrustManager mTrustManager;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700237 private UserManager mUserManager;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200238 private int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
239 private int mFaceRunningState = BIOMETRIC_STATE_STOPPED;
Michal Karpinskic52f8672016-11-18 11:32:45 +0000240 private LockPatternUtils mLockPatternUtils;
Kevin Chyn36778ff2017-09-07 19:55:38 -0700241 private final IDreamManager mDreamManager;
242 private boolean mIsDreaming;
Alex Chauff7653d2018-02-01 17:18:08 +0000243 private final DevicePolicyManager mDevicePolicyManager;
244 private boolean mLogoutEnabled;
Kevin Chyn1123ba72018-10-26 10:34:06 -0700245 private boolean mFingerprintLockedOut;
246 private boolean mFaceLockedOut;
Jim Miller20daffd2013-10-07 14:59:53 -0700247
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700248 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200249 * Short delay before restarting biometric authentication after a successful try
250 * This should be slightly longer than the time between on<biometric>Authenticated
251 * (e.g. onFingerprintAuthenticated) and setKeyguardGoingAway(true).
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700252 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200253 private static final int BIOMETRIC_CONTINUE_DELAY_MS = 500;
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700254
Kevin Chyn0c45b072017-04-24 16:27:11 -0700255 // If FP daemon dies, keyguard should retry after a short delay
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200256 private int mHardwareFingerprintUnavailableRetryCount = 0;
257 private int mHardwareFaceUnavailableRetryCount = 0;
Kevin Chyn0c45b072017-04-24 16:27:11 -0700258 private static final int HW_UNAVAILABLE_TIMEOUT = 3000; // ms
259 private static final int HW_UNAVAILABLE_RETRY_MAX = 3;
260
Jason Monk7bb59302018-05-10 19:38:18 -0700261 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700262 @Override
263 public void handleMessage(Message msg) {
264 switch (msg.what) {
265 case MSG_TIME_UPDATE:
266 handleTimeUpdate();
267 break;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500268 case MSG_TIMEZONE_UPDATE:
269 handleTimeZoneUpdate((String) msg.obj);
270 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700271 case MSG_BATTERY_UPDATE:
272 handleBatteryUpdate((BatteryStatus) msg.obj);
273 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700274 case MSG_SIM_STATE_CHANGE:
Jim Miller52a61332014-11-12 19:29:51 -0800275 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700276 break;
277 case MSG_RINGER_MODE_CHANGED:
278 handleRingerModeChange(msg.arg1);
279 break;
280 case MSG_PHONE_STATE_CHANGED:
Adrian Roosb6011622014-05-14 15:52:53 +0200281 handlePhoneStateChanged((String) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700282 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700283 case MSG_DEVICE_PROVISIONED:
284 handleDeviceProvisioned();
285 break;
286 case MSG_DPM_STATE_CHANGED:
287 handleDevicePolicyManagerStateChanged();
288 break;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500289 case MSG_USER_SWITCHING:
Adrian Roosb6011622014-05-14 15:52:53 +0200290 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
Chris Wrenf41c61b2012-11-29 15:19:54 -0500291 break;
292 case MSG_USER_SWITCH_COMPLETE:
293 handleUserSwitchComplete(msg.arg1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700294 break;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700295 case MSG_KEYGUARD_RESET:
296 handleKeyguardReset();
297 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200298 case MSG_KEYGUARD_BOUNCER_CHANGED:
299 handleKeyguardBouncerChanged(msg.arg1);
300 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800301 case MSG_BOOT_COMPLETED:
302 handleBootCompleted();
303 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700304 case MSG_USER_INFO_CHANGED:
305 handleUserInfoChanged(msg.arg1);
306 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400307 case MSG_REPORT_EMERGENCY_CALL_ACTION:
308 handleReportEmergencyCallAction();
309 break;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700310 case MSG_STARTED_GOING_TO_SLEEP:
311 handleStartedGoingToSleep(msg.arg1);
312 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700313 case MSG_FINISHED_GOING_TO_SLEEP:
314 handleFinishedGoingToSleep(msg.arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700315 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700316 case MSG_STARTED_WAKING_UP:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700317 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_STARTED_WAKING_UP");
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700318 handleStartedWakingUp();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700319 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -0700320 break;
Jorim Jaggie7b12522014-08-06 16:41:21 +0200321 case MSG_FACE_UNLOCK_STATE_CHANGED:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700322 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_FACE_UNLOCK_STATE_CHANGED");
Adrian Roos4a410172014-08-20 17:41:44 +0200323 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
Nick Desaulniers1d396752016-07-25 15:05:33 -0700324 Trace.endSection();
Jorim Jaggie7b12522014-08-06 16:41:21 +0200325 break;
Jim Miller52a61332014-11-12 19:29:51 -0800326 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
327 handleSimSubscriptionInfoChanged();
328 break;
Jason Monk052082c2015-06-11 11:35:23 -0400329 case MSG_AIRPLANE_MODE_CHANGED:
330 handleAirplaneModeChanged();
331 break;
Etan Cohen47051d82015-07-06 16:19:04 -0700332 case MSG_SERVICE_STATE_CHANGE:
333 handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
334 break;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700335 case MSG_SCREEN_TURNED_ON:
336 handleScreenTurnedOn();
337 break;
338 case MSG_SCREEN_TURNED_OFF:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700339 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_SCREEN_TURNED_ON");
Jorim Jaggif1518da2015-07-30 11:56:36 -0700340 handleScreenTurnedOff();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700341 Trace.endSection();
Jorim Jaggif1518da2015-07-30 11:56:36 -0700342 break;
Selim Cinek99415392016-09-09 14:58:41 -0700343 case MSG_DREAMING_STATE_CHANGED:
344 handleDreamingStateChanged(msg.arg1);
345 break;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700346 case MSG_USER_UNLOCKED:
347 handleUserUnlocked();
348 break;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700349 case MSG_ASSISTANT_STACK_CHANGED:
Lucas Dupin3d053532019-01-29 12:35:22 -0800350 setAssistantVisible((boolean) msg.obj);
Kevin Chyn2fefd462017-04-28 12:18:19 -0700351 break;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200352 case MSG_BIOMETRIC_AUTHENTICATION_CONTINUE:
353 updateBiometricListeningState();
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700354 break;
Alex Chauff7653d2018-02-01 17:18:08 +0000355 case MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED:
356 updateLogoutEnabled();
357 break;
Bill Linef81cbd2018-07-05 17:48:49 +0800358 case MSG_TELEPHONY_CAPABLE:
Lucas Dupin3d053532019-01-29 12:35:22 -0800359 updateTelephonyCapable((boolean) msg.obj);
Bill Linef81cbd2018-07-05 17:48:49 +0800360 break;
Jason Monk7bb59302018-05-10 19:38:18 -0700361 default:
362 super.handleMessage(msg);
363 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700364 }
365 }
366 };
367
Kevin Chynb7b54a62018-09-28 18:48:12 -0700368 private boolean mFaceSettingEnabledForUser;
369 private BiometricManager mBiometricManager;
370 private IBiometricEnabledOnKeyguardCallback mBiometricEnabledCallback =
371 new IBiometricEnabledOnKeyguardCallback.Stub() {
372 @Override
373 public void onChanged(BiometricSourceType type, boolean enabled) throws RemoteException {
374 if (type == BiometricSourceType.FACE) {
375 mFaceSettingEnabledForUser = enabled;
376 }
377 }
378 };
379
Wink Savilled09c4ca2014-11-22 10:08:16 -0800380 private OnSubscriptionsChangedListener mSubscriptionListener =
381 new OnSubscriptionsChangedListener() {
Jim Miller52a61332014-11-12 19:29:51 -0800382 @Override
Wink Savilled09c4ca2014-11-22 10:08:16 -0800383 public void onSubscriptionsChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800384 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
385 }
386 };
387
Adrian Roos46842d92014-03-27 14:58:03 +0100388 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200389 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Jim Miller9f0753f2015-03-23 23:59:22 -0700390 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200391 private SparseBooleanArray mUserFaceAuthenticated = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200392 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100393
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700394 private static int sCurrentUser;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200395 private Runnable mUpdateBiometricListeningState = this::updateBiometricListeningState;
Adrian Roos30a2ae62018-04-25 19:09:50 +0200396 private static boolean sDisableHandlerCheckForTesting;
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700397
398 public synchronized static void setCurrentUser(int currentUser) {
399 sCurrentUser = currentUser;
400 }
401
402 public synchronized static int getCurrentUser() {
403 return sCurrentUser;
404 }
405
Adrian Roos46842d92014-03-27 14:58:03 +0100406 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700407 public void onTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200408 checkIsHandlerThread();
Adrian Roos46842d92014-03-27 14:58:03 +0100409 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200410 for (int i = 0; i < mCallbacks.size(); i++) {
411 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
412 if (cb != null) {
413 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700414 if (enabled && flags != 0) {
415 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200416 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200417 }
418 }
Adrian Roos46842d92014-03-27 14:58:03 +0100419 }
420
Lucas Dupinef886542018-01-03 16:03:07 -0800421 @Override
422 public void onTrustError(CharSequence message) {
423 dispatchErrorMessage(message);
424 }
425
Adrian Roos30a2ae62018-04-25 19:09:50 +0200426 private void handleSimSubscriptionInfoChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800427 if (DEBUG_SIM_STATES) {
428 Log.v(TAG, "onSubscriptionInfoChanged()");
Wink Savilled09c4ca2014-11-22 10:08:16 -0800429 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
430 if (sil != null) {
431 for (SubscriptionInfo subInfo : sil) {
432 Log.v(TAG, "SubInfo:" + subInfo);
433 }
434 } else {
435 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800436 }
437 }
438 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
439
440 // Hack level over 9000: Because the subscription id is not yet valid when we see the
441 // first update in handleSimStateChange, we need to force refresh all all SIM states
442 // so the subscription id for them is consistent.
Richard Choue0381b82018-04-24 03:48:59 +0000443 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
444 for (int i = 0; i < subscriptionInfos.size(); i++) {
445 SubscriptionInfo info = subscriptionInfos.get(i);
446 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
447 if (changed) {
448 changedSubscriptions.add(info);
449 }
450 }
451 for (int i = 0; i < changedSubscriptions.size(); i++) {
452 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800453 for (int j = 0; j < mCallbacks.size(); j++) {
454 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
455 if (cb != null) {
456 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
457 }
458 }
459 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500460 for (int j = 0; j < mCallbacks.size(); j++) {
461 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
462 if (cb != null) {
463 cb.onRefreshCarrierInfo();
464 }
465 }
Jim Miller52a61332014-11-12 19:29:51 -0800466 }
467
Jason Monk052082c2015-06-11 11:35:23 -0400468 private void handleAirplaneModeChanged() {
469 for (int j = 0; j < mCallbacks.size(); j++) {
470 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
471 if (cb != null) {
472 cb.onRefreshCarrierInfo();
473 }
474 }
475 }
476
Wink Savilled09c4ca2014-11-22 10:08:16 -0800477 /** @return List of SubscriptionInfo records, maybe empty but never null */
Adrian Roos316bf542016-08-23 17:53:07 +0200478 public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800479 List<SubscriptionInfo> sil = mSubscriptionInfo;
480 if (sil == null || forceReload) {
481 sil = mSubscriptionManager.getActiveSubscriptionInfoList();
482 }
483 if (sil == null) {
484 // getActiveSubscriptionInfoList was null callers expect an empty list.
485 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
486 } else {
487 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800488 }
489 return mSubscriptionInfo;
490 }
491
Adrian Roos7861c662014-07-25 15:37:28 +0200492 @Override
493 public void onTrustManagedChanged(boolean managed, int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200494 checkIsHandlerThread();
Adrian Roos7861c662014-07-25 15:37:28 +0200495 mUserTrustIsManaged.put(userId, managed);
496
497 for (int i = 0; i < mCallbacks.size(); i++) {
498 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
499 if (cb != null) {
500 cb.onTrustManagedChanged(userId);
501 }
502 }
503 }
504
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700505 /**
506 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is goingAway
507 * @param goingAway
508 */
509 public void setKeyguardGoingAway(boolean goingAway) {
510 mKeyguardGoingAway = goingAway;
Kevin Chyne22f1342017-09-26 10:03:38 -0700511 updateFingerprintListeningState();
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700512 }
513
Kevin Chyn2fefd462017-04-28 12:18:19 -0700514 /**
515 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is occluded
516 * @param occluded
517 */
518 public void setKeyguardOccluded(boolean occluded) {
519 mKeyguardOccluded = occluded;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200520 updateBiometricListeningState();
Kevin Chyn2fefd462017-04-28 12:18:19 -0700521 }
522
Kevin Chyn36778ff2017-09-07 19:55:38 -0700523 /**
524 * @return a cached version of DreamManager.isDreaming()
525 */
526 public boolean isDreaming() {
527 return mIsDreaming;
528 }
529
530 /**
531 * If the device is dreaming, awakens the device
532 */
533 public void awakenFromDream() {
534 if (mIsDreaming && mDreamManager != null) {
535 try {
536 mDreamManager.awaken();
537 } catch (RemoteException e) {
538 Log.e(TAG, "Unable to awaken from dream");
539 }
540 }
541 }
542
Lucas Dupin3d053532019-01-29 12:35:22 -0800543 @VisibleForTesting
544 protected void onFingerprintAuthenticated(int userId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700545 Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
Jim Miller9f0753f2015-03-23 23:59:22 -0700546 mUserFingerprintAuthenticated.put(userId, true);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700547 // Update/refresh trust state only if user can skip bouncer
548 if (getUserCanSkipBouncer(userId)) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200549 mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FINGERPRINT);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700550 }
Kevin Chyn625a0142017-04-10 14:53:59 -0700551 // Don't send cancel if authentication succeeds
552 mFingerprintCancelSignal = null;
Jim Millerf41fc962014-06-18 16:33:51 -0700553 for (int i = 0; i < mCallbacks.size(); i++) {
554 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
555 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200556 cb.onBiometricAuthenticated(userId, BiometricSourceType.FINGERPRINT);
Jim Millerf41fc962014-06-18 16:33:51 -0700557 }
558 }
Kevin Chyn2fefd462017-04-28 12:18:19 -0700559
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200560 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE),
561 BIOMETRIC_CONTINUE_DELAY_MS);
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700562
Kevin Chyn2fefd462017-04-28 12:18:19 -0700563 // Only authenticate fingerprint once when assistant is visible
564 mAssistantVisible = false;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700565
Nick Desaulniers1d396752016-07-25 15:05:33 -0700566 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700567 }
568
Jim Millerce7eb6d2015-04-03 19:29:13 -0700569 private void handleFingerprintAuthFailed() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700570 for (int i = 0; i < mCallbacks.size(); i++) {
571 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
572 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200573 cb.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700574 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700575 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200576 handleFingerprintHelp(-1, mContext.getString(R.string.kg_fingerprint_not_recognized));
Jim Millerce7eb6d2015-04-03 19:29:13 -0700577 }
Jim Millerf41fc962014-06-18 16:33:51 -0700578
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700579 private void handleFingerprintAcquired(int acquireInfo) {
580 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
581 return;
582 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700583 for (int i = 0; i < mCallbacks.size(); i++) {
584 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
585 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200586 cb.onBiometricAcquired(BiometricSourceType.FINGERPRINT);
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700587 }
588 }
589 }
590
Jim Miller837fa7e2016-08-08 20:16:22 -0700591 private void handleFingerprintAuthenticated(int authUserId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700592 Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
Jim Millerf41fc962014-06-18 16:33:51 -0700593 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700594 final int userId;
595 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800596 userId = ActivityManager.getService().getCurrentUser().id;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700597 } catch (RemoteException e) {
598 Log.e(TAG, "Failed to get current user id: ", e);
599 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700600 }
Jim Miller837fa7e2016-08-08 20:16:22 -0700601 if (userId != authUserId) {
602 Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId);
603 return;
604 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700605 if (isFingerprintDisabled(userId)) {
606 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
607 return;
608 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700609 onFingerprintAuthenticated(userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700610 } finally {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200611 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Jim Millerf41fc962014-06-18 16:33:51 -0700612 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700613 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700614 }
615
Jim Miller9f0753f2015-03-23 23:59:22 -0700616 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700617 for (int i = 0; i < mCallbacks.size(); i++) {
618 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
619 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200620 cb.onBiometricHelp(msgId, helpString, BiometricSourceType.FINGERPRINT);
Jim Miller9f0753f2015-03-23 23:59:22 -0700621 }
622 }
623 }
624
Kevin Chyn0c45b072017-04-24 16:27:11 -0700625 private Runnable mRetryFingerprintAuthentication = new Runnable() {
626 @Override
627 public void run() {
628 Log.w(TAG, "Retrying fingerprint after HW unavailable, attempt " +
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200629 mHardwareFingerprintUnavailableRetryCount);
Kevin Chyn0c45b072017-04-24 16:27:11 -0700630 updateFingerprintListeningState();
631 }
632 };
633
Jim Miller9f0753f2015-03-23 23:59:22 -0700634 private void handleFingerprintError(int msgId, String errString) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700635 if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200636 && mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
637 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Kevin Chyn1123ba72018-10-26 10:34:06 -0700638 updateFingerprintListeningState();
Jorim Jaggi86bed402015-08-20 18:20:02 -0700639 } else {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200640 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Jorim Jaggi86bed402015-08-20 18:20:02 -0700641 }
Kevin Chyn0c45b072017-04-24 16:27:11 -0700642
643 if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200644 if (mHardwareFingerprintUnavailableRetryCount < HW_UNAVAILABLE_RETRY_MAX) {
645 mHardwareFingerprintUnavailableRetryCount++;
Kevin Chyn0c45b072017-04-24 16:27:11 -0700646 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
647 mHandler.postDelayed(mRetryFingerprintAuthentication, HW_UNAVAILABLE_TIMEOUT);
648 }
649 }
650
Kevin Chyn1123ba72018-10-26 10:34:06 -0700651 if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT
652 || msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
653 mFingerprintLockedOut = true;
654 }
655
Kevin Chyndf9d33e2017-05-03 21:40:12 -0700656 if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
657 mLockPatternUtils.requireStrongAuth(
658 LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
659 getCurrentUser());
660 }
661
Jim Miller9f0753f2015-03-23 23:59:22 -0700662 for (int i = 0; i < mCallbacks.size(); i++) {
663 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
664 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200665 cb.onBiometricError(msgId, errString, BiometricSourceType.FINGERPRINT);
Jim Millerf41fc962014-06-18 16:33:51 -0700666 }
667 }
668 }
669
Jorim Jaggi3a464782015-08-28 16:59:13 -0700670 private void handleFingerprintLockoutReset() {
Kevin Chyn1123ba72018-10-26 10:34:06 -0700671 mFingerprintLockedOut = false;
Jorim Jaggi3a464782015-08-28 16:59:13 -0700672 updateFingerprintListeningState();
673 }
674
Jorim Jaggi86bed402015-08-20 18:20:02 -0700675 private void setFingerprintRunningState(int fingerprintRunningState) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200676 boolean wasRunning = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
677 boolean isRunning = fingerprintRunningState == BIOMETRIC_STATE_RUNNING;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700678 mFingerprintRunningState = fingerprintRunningState;
Kevin Chyn1123ba72018-10-26 10:34:06 -0700679 if (DEBUG) Log.v(TAG, "Fingerprint State: " + mFingerprintRunningState);
Jorim Jaggi86bed402015-08-20 18:20:02 -0700680 // Clients of KeyguardUpdateMonitor don't care about the internal state about the
681 // asynchronousness of the cancel cycle. So only notify them if the actualy running state
682 // has changed.
683 if (wasRunning != isRunning) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700684 notifyFingerprintRunningStateChanged();
685 }
686 }
687
688 private void notifyFingerprintRunningStateChanged() {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200689 checkIsHandlerThread();
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700690 for (int i = 0; i < mCallbacks.size(); i++) {
691 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
692 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200693 cb.onBiometricRunningStateChanged(isFingerprintDetectionRunning(),
694 BiometricSourceType.FINGERPRINT);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700695 }
696 }
697 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200698
Lucas Dupin3d053532019-01-29 12:35:22 -0800699 @VisibleForTesting
700 protected void onFaceAuthenticated(int userId) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200701 Trace.beginSection("KeyGuardUpdateMonitor#onFaceAuthenticated");
702 mUserFaceAuthenticated.put(userId, true);
703 // Update/refresh trust state only if user can skip bouncer
704 if (getUserCanSkipBouncer(userId)) {
705 mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FACE);
706 }
707 // Don't send cancel if authentication succeeds
708 mFaceCancelSignal = null;
709 for (int i = 0; i < mCallbacks.size(); i++) {
710 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
711 if (cb != null) {
712 cb.onBiometricAuthenticated(userId,
713 BiometricSourceType.FACE);
714 }
715 }
716
717 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE),
718 BIOMETRIC_CONTINUE_DELAY_MS);
719
720 // Only authenticate face once when assistant is visible
721 mAssistantVisible = false;
722
723 Trace.endSection();
724 }
725
726 private void handleFaceAuthFailed() {
Lucas Dupin38314812019-02-15 14:10:55 -0800727 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200728 for (int i = 0; i < mCallbacks.size(); i++) {
729 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
730 if (cb != null) {
731 cb.onBiometricAuthFailed(BiometricSourceType.FACE);
732 }
733 }
734 handleFaceHelp(-1, mContext.getString(R.string.kg_face_not_recognized));
735 }
736
737 private void handleFaceAcquired(int acquireInfo) {
738 if (acquireInfo != FaceManager.FACE_ACQUIRED_GOOD) {
739 return;
740 }
741 for (int i = 0; i < mCallbacks.size(); i++) {
742 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
743 if (cb != null) {
744 cb.onBiometricAcquired(BiometricSourceType.FACE);
745 }
746 }
747 }
748
749 private void handleFaceAuthenticated(int authUserId) {
750 Trace.beginSection("KeyGuardUpdateMonitor#handlerFaceAuthenticated");
751 try {
752 final int userId;
753 try {
754 userId = ActivityManager.getService().getCurrentUser().id;
755 } catch (RemoteException e) {
756 Log.e(TAG, "Failed to get current user id: ", e);
757 return;
758 }
759 if (userId != authUserId) {
760 Log.d(TAG, "Face authenticated for wrong user: " + authUserId);
761 return;
762 }
763 if (isFaceDisabled(userId)) {
764 Log.d(TAG, "Face authentication disabled by DPM for userId: " + userId);
765 return;
766 }
767 onFaceAuthenticated(userId);
768 } finally {
769 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
770 }
771 Trace.endSection();
772 }
773
774 private void handleFaceHelp(int msgId, String helpString) {
775 for (int i = 0; i < mCallbacks.size(); i++) {
776 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
777 if (cb != null) {
778 cb.onBiometricHelp(msgId, helpString, BiometricSourceType.FACE);
779 }
780 }
781 }
782
783 private Runnable mRetryFaceAuthentication = new Runnable() {
784 @Override
785 public void run() {
786 Log.w(TAG, "Retrying face after HW unavailable, attempt " +
787 mHardwareFaceUnavailableRetryCount);
788 updateFaceListeningState();
789 }
790 };
791
792 private void handleFaceError(int msgId, String errString) {
793 if (msgId == FaceManager.FACE_ERROR_CANCELED
794 && mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
795 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
Kevin Chyn1123ba72018-10-26 10:34:06 -0700796 updateFaceListeningState();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200797 } else {
798 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
799 }
800
801 if (msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE) {
802 if (mHardwareFaceUnavailableRetryCount < HW_UNAVAILABLE_RETRY_MAX) {
803 mHardwareFaceUnavailableRetryCount++;
804 mHandler.removeCallbacks(mRetryFaceAuthentication);
805 mHandler.postDelayed(mRetryFaceAuthentication, HW_UNAVAILABLE_TIMEOUT);
806 }
807 }
808
Kevin Chyn1123ba72018-10-26 10:34:06 -0700809 if (msgId == FaceManager.FACE_ERROR_LOCKOUT
810 || msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
811 mFaceLockedOut = true;
812 }
813
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200814 if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
815 mLockPatternUtils.requireStrongAuth(
816 LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
817 getCurrentUser());
818 }
819
820 for (int i = 0; i < mCallbacks.size(); i++) {
821 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
822 if (cb != null) {
823 cb.onBiometricError(msgId, errString,
824 BiometricSourceType.FACE);
825 }
826 }
827 }
828
829 private void handleFaceLockoutReset() {
Kevin Chyn1123ba72018-10-26 10:34:06 -0700830 mFaceLockedOut = false;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200831 updateFaceListeningState();
832 }
833
834 private void setFaceRunningState(int faceRunningState) {
835 boolean wasRunning = mFaceRunningState == BIOMETRIC_STATE_RUNNING;
836 boolean isRunning = faceRunningState == BIOMETRIC_STATE_RUNNING;
837 mFaceRunningState = faceRunningState;
Kevin Chyn1123ba72018-10-26 10:34:06 -0700838 if (DEBUG) Log.v(TAG, "Face State: " + mFaceRunningState);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200839 // Clients of KeyguardUpdateMonitor don't care about the internal state or about the
840 // asynchronousness of the cancel cycle. So only notify them if the actualy running state
841 // has changed.
842 if (wasRunning != isRunning) {
843 notifyFaceRunningStateChanged();
844 }
845 }
846
847 private void notifyFaceRunningStateChanged() {
848 for (int i = 0; i < mCallbacks.size(); i++) {
849 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
850 if (cb != null) {
851 cb.onBiometricRunningStateChanged(isFaceDetectionRunning(),
852 BiometricSourceType.FACE);
853 }
854 }
855 }
856
Adrian Roos4a410172014-08-20 17:41:44 +0200857 private void handleFaceUnlockStateChanged(boolean running, int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200858 checkIsHandlerThread();
Adrian Roos4a410172014-08-20 17:41:44 +0200859 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200860 for (int i = 0; i < mCallbacks.size(); i++) {
861 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
862 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200863 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200864 }
865 }
866 }
867
Adrian Roos4a410172014-08-20 17:41:44 +0200868 public boolean isFaceUnlockRunning(int userId) {
869 return mUserFaceUnlockRunning.get(userId);
870 }
871
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700872 public boolean isFingerprintDetectionRunning() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200873 return mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
874 }
875
876 public boolean isFaceDetectionRunning() {
877 return mFaceRunningState == BIOMETRIC_STATE_RUNNING;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700878 }
879
Jim Miller50e62182014-04-23 17:25:00 -0700880 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100881 // Don't allow trust agent if device is secured with a SIM PIN. This is here
882 // mainly because there's no other way to prompt the user to enter their SIM PIN
883 // once they get past the keyguard screen.
884 final boolean disabledBySimPin = isSimPinSecure();
885 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700886 }
887
Jim Miller06e34502014-07-17 14:46:05 -0700888 private boolean isFingerprintDisabled(int userId) {
889 final DevicePolicyManager dpm =
890 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
891 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
Adrian Roos733b6632015-08-21 14:32:35 -0700892 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0
893 || isSimPinSecure();
Jim Miller06e34502014-07-17 14:46:05 -0700894 }
895
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200896 private boolean isFaceDisabled(int userId) {
897 final DevicePolicyManager dpm =
898 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
899 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
900 & DevicePolicyManager.KEYGUARD_DISABLE_FACE) != 0
901 || isSimPinSecure();
902 }
903
904
Selim Cineke8bae622015-07-15 13:24:06 -0700905 public boolean getUserCanSkipBouncer(int userId) {
Lucas Dupin3d053532019-01-29 12:35:22 -0800906 boolean fingerprintOrFace = mUserFingerprintAuthenticated.get(userId)
907 || mUserFaceAuthenticated.get(userId);
908 return getUserHasTrust(userId) || (fingerprintOrFace && isUnlockingWithBiometricAllowed());
Selim Cineke8bae622015-07-15 13:24:06 -0700909 }
910
Adrian Roos46842d92014-03-27 14:58:03 +0100911 public boolean getUserHasTrust(int userId) {
Selim Cineke8bae622015-07-15 13:24:06 -0700912 return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100913 }
914
Adrian Roos7861c662014-07-25 15:37:28 +0200915 public boolean getUserTrustIsManaged(int userId) {
916 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
917 }
918
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200919 public boolean isUnlockingWithBiometricAllowed() {
920 return mStrongAuthTracker.isUnlockingWithBiometricAllowed();
Adrian Roosb5e47222015-08-14 15:53:06 -0700921 }
922
Lucas Dupin16013822018-05-17 18:00:16 -0700923 public boolean isUserInLockdown(int userId) {
924 return mStrongAuthTracker.getStrongAuthForUser(userId)
925 == LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
926 }
927
Jorim Jaggi031f7952016-09-01 16:39:26 -0700928 public boolean needsSlowUnlockTransition() {
929 return mNeedsSlowUnlockTransition;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700930 }
931
Adrian Roosb5e47222015-08-14 15:53:06 -0700932 public StrongAuthTracker getStrongAuthTracker() {
933 return mStrongAuthTracker;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700934 }
935
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700936 private void notifyStrongAuthStateChanged(int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200937 checkIsHandlerThread();
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700938 for (int i = 0; i < mCallbacks.size(); i++) {
939 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
940 if (cb != null) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700941 cb.onStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700942 }
943 }
Selim Cinek1fcafc42015-07-20 14:39:25 -0700944 }
945
Adrian Roos91ba3072017-02-14 16:50:46 +0100946 public boolean isScreenOn() {
947 return mScreenOn;
948 }
949
Lucas Dupinef886542018-01-03 16:03:07 -0800950 private void dispatchErrorMessage(CharSequence message) {
951 for (int i = 0; i < mCallbacks.size(); i++) {
952 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
953 if (cb != null) {
954 cb.onTrustAgentErrorMessage(message);
955 }
956 }
957 }
958
Lucas Dupin3d053532019-01-29 12:35:22 -0800959 @VisibleForTesting
960 void setAssistantVisible(boolean assistantVisible) {
961 mAssistantVisible = assistantVisible;
962 updateBiometricListeningState();
963 }
964
Jim Miller8f09fd22013-03-14 19:04:28 -0700965 static class DisplayClientState {
966 public int clientGeneration;
967 public boolean clearing;
968 public PendingIntent intent;
969 public int playbackState;
970 public long playbackEventTime;
971 }
972
973 private DisplayClientState mDisplayClientState = new DisplayClientState();
974
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800975 @VisibleForTesting
Lucas Dupin7ff82b02018-05-16 12:14:10 -0700976 protected final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
Jim Millerbbf1a742012-07-17 18:30:30 -0700977
Jim Millerd72d5ac2015-09-29 18:55:32 -0700978 @Override
Jim Millerbbf1a742012-07-17 18:30:30 -0700979 public void onReceive(Context context, Intent intent) {
980 final String action = intent.getAction();
981 if (DEBUG) Log.d(TAG, "received broadcast " + action);
982
983 if (Intent.ACTION_TIME_TICK.equals(action)
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500984 || Intent.ACTION_TIME_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700985 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500986 } else if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
987 final Message msg = mHandler.obtainMessage(
988 MSG_TIMEZONE_UPDATE, intent.getStringExtra("time-zone"));
989 mHandler.sendMessage(msg);
Jim Millerbbf1a742012-07-17 18:30:30 -0700990 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
991 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
992 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
993 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
994 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
Adrian Roos0c859ae2015-11-23 16:47:50 -0800995
996 final int maxChargingMicroAmp = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
997 int maxChargingMicroVolt = intent.getIntExtra(EXTRA_MAX_CHARGING_VOLTAGE, -1);
998 final int maxChargingMicroWatt;
999
1000 if (maxChargingMicroVolt <= 0) {
1001 maxChargingMicroVolt = DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT;
1002 }
1003 if (maxChargingMicroAmp > 0) {
1004 // Calculating muW = muA * muV / (10^6 mu^2 / mu); splitting up the divisor
1005 // to maintain precision equally on both factors.
1006 maxChargingMicroWatt = (maxChargingMicroAmp / 1000)
1007 * (maxChargingMicroVolt / 1000);
1008 } else {
1009 maxChargingMicroWatt = -1;
1010 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001011 final Message msg = mHandler.obtainMessage(
Adrian Roos7b043112015-07-10 13:00:33 -07001012 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
Adrian Roos0c859ae2015-11-23 16:47:50 -08001013 maxChargingMicroWatt));
Jim Millerbbf1a742012-07-17 18:30:30 -07001014 mHandler.sendMessage(msg);
1015 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Bill Linef81cbd2018-07-05 17:48:49 +08001016 SimData args = SimData.fromIntent(intent);
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001017 // ACTION_SIM_STATE_CHANGED is rebroadcast after unlocking the device to
1018 // keep compatibility with apps that aren't direct boot aware.
1019 // SysUI should just ignore this broadcast because it was already received
1020 // and processed previously.
1021 if (intent.getBooleanExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
Bill Linef81cbd2018-07-05 17:48:49 +08001022 // Guarantee mTelephonyCapable state after SysUI crash and restart
1023 if (args.simState == State.ABSENT) {
1024 mHandler.obtainMessage(MSG_TELEPHONY_CAPABLE, true).sendToTarget();
1025 }
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001026 return;
1027 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001028 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -08001029 Log.v(TAG, "action " + action
1030 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
1031 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -07001032 }
Jim Miller52a61332014-11-12 19:29:51 -08001033 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
1034 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -07001035 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
1036 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
1037 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
1038 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
1039 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
1040 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Jason Monk052082c2015-06-11 11:35:23 -04001041 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
1042 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001043 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -07001044 dispatchBootCompleted();
Etan Cohen47051d82015-07-06 16:19:04 -07001045 } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
1046 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
1047 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
1048 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
1049 if (DEBUG) {
1050 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
1051 + subId);
1052 }
1053 mHandler.sendMessage(
1054 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
Alex Chauff7653d2018-02-01 17:18:08 +00001055 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
1056 action)) {
1057 mHandler.sendEmptyMessage(MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001058 }
1059 }
1060 };
Jim Miller2de5ee82012-06-14 22:22:50 -07001061
Lucas Dupin3d053532019-01-29 12:35:22 -08001062 @VisibleForTesting
1063 protected final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001064
Jim Millerd72d5ac2015-09-29 18:55:32 -07001065 @Override
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001066 public void onReceive(Context context, Intent intent) {
1067 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +02001068 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
1069 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
1070 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001071 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
1072 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +02001073 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001074 Trace.beginSection("KeyguardUpdateMonitor.mBroadcastAllReceiver#onReceive ACTION_FACE_UNLOCK_STARTED");
Adrian Roos48c796c2014-09-01 14:59:23 +02001075 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
1076 getSendingUserId()));
Nick Desaulniers1d396752016-07-25 15:05:33 -07001077 Trace.endSection();
Adrian Roos48c796c2014-09-01 14:59:23 +02001078 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
1079 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
1080 getSendingUserId()));
1081 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
1082 .equals(action)) {
1083 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001084 } else if (ACTION_USER_UNLOCKED.equals(action)) {
1085 mHandler.sendEmptyMessage(MSG_USER_UNLOCKED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001086 }
1087 }
1088 };
Jim Miller9f0753f2015-03-23 23:59:22 -07001089
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001090 private final FingerprintManager.LockoutResetCallback mFingerprintLockoutResetCallback
Jorim Jaggi3a464782015-08-28 16:59:13 -07001091 = new FingerprintManager.LockoutResetCallback() {
1092 @Override
1093 public void onLockoutReset() {
1094 handleFingerprintLockoutReset();
1095 }
1096 };
1097
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001098 private final FaceManager.LockoutResetCallback mFaceLockoutResetCallback
1099 = new FaceManager.LockoutResetCallback() {
1100 @Override
1101 public void onLockoutReset() {
1102 handleFaceLockoutReset();
1103 }
1104 };
1105
1106 private FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback
Jim Miller9f0753f2015-03-23 23:59:22 -07001107 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -07001108
1109 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -07001110 public void onAuthenticationFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001111 handleFingerprintAuthFailed();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001112 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001113
1114 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -07001115 public void onAuthenticationSucceeded(AuthenticationResult result) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001116 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
Jim Miller837fa7e2016-08-08 20:16:22 -07001117 handleFingerprintAuthenticated(result.getUserId());
Nick Desaulniers1d396752016-07-25 15:05:33 -07001118 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -07001119 }
1120
1121 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -07001122 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001123 handleFingerprintHelp(helpMsgId, helpString.toString());
Jim Miller9f0753f2015-03-23 23:59:22 -07001124 }
1125
1126 @Override
1127 public void onAuthenticationError(int errMsgId, CharSequence errString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001128 handleFingerprintError(errMsgId, errString.toString());
1129 }
1130
1131 @Override
1132 public void onAuthenticationAcquired(int acquireInfo) {
1133 handleFingerprintAcquired(acquireInfo);
Jim Millerf41fc962014-06-18 16:33:51 -07001134 }
1135 };
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001136
Lucas Dupin3d053532019-01-29 12:35:22 -08001137 @VisibleForTesting
1138 FaceManager.AuthenticationCallback mFaceAuthenticationCallback
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001139 = new FaceManager.AuthenticationCallback() {
1140
1141 @Override
1142 public void onAuthenticationFailed() {
1143 handleFaceAuthFailed();
1144 }
1145
1146 @Override
1147 public void onAuthenticationSucceeded(FaceManager.AuthenticationResult result) {
1148 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
1149 handleFaceAuthenticated(result.getUserId());
1150 Trace.endSection();
1151 }
1152
1153 @Override
1154 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
1155 handleFaceHelp(helpMsgId, helpString.toString());
1156 }
1157
1158 @Override
1159 public void onAuthenticationError(int errMsgId, CharSequence errString) {
1160 handleFaceError(errMsgId, errString.toString());
1161 }
1162
1163 @Override
1164 public void onAuthenticationAcquired(int acquireInfo) {
1165 handleFaceAcquired(acquireInfo);
1166 }
1167 };
1168
Jim Miller9f0753f2015-03-23 23:59:22 -07001169 private CancellationSignal mFingerprintCancelSignal;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001170 private CancellationSignal mFaceCancelSignal;
Jim Miller9f0753f2015-03-23 23:59:22 -07001171 private FingerprintManager mFpm;
Kevin Chynb7b54a62018-09-28 18:48:12 -07001172 private FaceManager mFaceManager;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001173
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001174 /**
Jim Miller47088bb2009-11-24 00:40:16 -08001175 * When we receive a
1176 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -07001177 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001178 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -08001179 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001180 */
Jim Miller52a61332014-11-12 19:29:51 -08001181 private static class SimData {
1182 public State simState;
1183 public int slotId;
1184 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001185
Jim Miller52a61332014-11-12 19:29:51 -08001186 SimData(State state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -08001187 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -08001188 slotId = slot;
1189 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -08001190 }
1191
Jim Miller52a61332014-11-12 19:29:51 -08001192 static SimData fromIntent(Intent intent) {
1193 State state;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001194 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
1195 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
1196 }
Wink Savillea639b312012-07-10 12:37:54 -07001197 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
Jim Miller52a61332014-11-12 19:29:51 -08001198 int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0);
1199 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
Wink Savilled09c4ca2014-11-22 10:08:16 -08001200 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea639b312012-07-10 12:37:54 -07001201 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -07001202 final String absentReason = intent
Wink Savillea639b312012-07-10 12:37:54 -07001203 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -07001204
Wink Savillea639b312012-07-10 12:37:54 -07001205 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -07001206 absentReason)) {
Wink Savillea639b312012-07-10 12:37:54 -07001207 state = IccCardConstants.State.PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -07001208 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001209 state = IccCardConstants.State.ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -07001210 }
Wink Savillea639b312012-07-10 12:37:54 -07001211 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
1212 state = IccCardConstants.State.READY;
1213 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001214 final String lockedReason = intent
Wink Savillea639b312012-07-10 12:37:54 -07001215 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
1216 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
1217 state = IccCardConstants.State.PIN_REQUIRED;
1218 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
1219 state = IccCardConstants.State.PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001220 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001221 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001222 }
Wink Savillea639b312012-07-10 12:37:54 -07001223 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
1224 state = IccCardConstants.State.NETWORK_LOCKED;
Wileen Chiu6b8b22e2014-10-29 22:48:21 +05301225 } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
1226 state = IccCardConstants.State.CARD_IO_ERROR;
Jim Miller109f1fd2012-09-19 20:44:16 -07001227 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
1228 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
1229 // This is required because telephony doesn't return to "READY" after
1230 // these state transitions. See bug 7197471.
1231 state = IccCardConstants.State.READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001232 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001233 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001234 }
Jim Miller52a61332014-11-12 19:29:51 -08001235 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001236 }
1237
Jim Millerd72d5ac2015-09-29 18:55:32 -07001238 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001239 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -08001240 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001241 }
1242 }
1243
Adrian Roos12c1ef52014-06-04 13:54:08 +02001244 public static class BatteryStatus {
Adrian Roos7b043112015-07-10 13:00:33 -07001245 public static final int CHARGING_UNKNOWN = -1;
1246 public static final int CHARGING_SLOWLY = 0;
1247 public static final int CHARGING_REGULAR = 1;
1248 public static final int CHARGING_FAST = 2;
1249
Jim Miller16464b82011-10-20 21:10:13 -07001250 public final int status;
1251 public final int level;
1252 public final int plugged;
1253 public final int health;
Adrian Roos0c859ae2015-11-23 16:47:50 -08001254 public final int maxChargingWattage;
1255 public BatteryStatus(int status, int level, int plugged, int health,
1256 int maxChargingWattage) {
Jim Miller16464b82011-10-20 21:10:13 -07001257 this.status = status;
1258 this.level = level;
1259 this.plugged = plugged;
1260 this.health = health;
Adrian Roos0c859ae2015-11-23 16:47:50 -08001261 this.maxChargingWattage = maxChargingWattage;
Jim Miller16464b82011-10-20 21:10:13 -07001262 }
1263
Jim Millerbbf1a742012-07-17 18:30:30 -07001264 /**
Brian Muramatsua92a01b2012-09-05 21:54:39 -07001265 * Determine whether the device is plugged in (USB, power, or wireless).
Jim Millerbbf1a742012-07-17 18:30:30 -07001266 * @return true if the device is plugged in.
1267 */
Adrian Roosad3bc7f2014-10-30 18:29:38 +01001268 public boolean isPluggedIn() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001269 return plugged == BatteryManager.BATTERY_PLUGGED_AC
Brian Muramatsua92a01b2012-09-05 21:54:39 -07001270 || plugged == BatteryManager.BATTERY_PLUGGED_USB
1271 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Jim Millerbbf1a742012-07-17 18:30:30 -07001272 }
1273
1274 /**
Beverly2034c832018-03-19 11:18:51 -04001275 * Determine whether the device is plugged in (USB, power).
1276 * @return true if the device is plugged in wired (as opposed to wireless)
1277 */
1278 public boolean isPluggedInWired() {
1279 return plugged == BatteryManager.BATTERY_PLUGGED_AC
1280 || plugged == BatteryManager.BATTERY_PLUGGED_USB;
1281 }
1282
1283 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001284 * Whether or not the device is charged. Note that some devices never return 100% for
1285 * battery level, so this allows either battery level or status to determine if the
1286 * battery is charged.
1287 * @return true if the device is charged
1288 */
1289 public boolean isCharged() {
1290 return status == BATTERY_STATUS_FULL || level >= 100;
1291 }
1292
1293 /**
1294 * Whether battery is low and needs to be charged.
1295 * @return true if battery is low
1296 */
1297 public boolean isBatteryLow() {
1298 return level < LOW_BATTERY_THRESHOLD;
1299 }
1300
Adrian Roos7b043112015-07-10 13:00:33 -07001301 public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
Adrian Roos0c859ae2015-11-23 16:47:50 -08001302 return maxChargingWattage <= 0 ? CHARGING_UNKNOWN :
1303 maxChargingWattage < slowThreshold ? CHARGING_SLOWLY :
1304 maxChargingWattage > fastThreshold ? CHARGING_FAST :
Adrian Roos7b043112015-07-10 13:00:33 -07001305 CHARGING_REGULAR;
1306 }
Lucas Dupin3fcdd472018-01-19 19:06:45 -08001307
1308 @Override
1309 public String toString() {
1310 return "BatteryStatus{status=" + status + ",level=" + level + ",plugged=" + plugged
1311 + ",health=" + health + ",maxChargingWattage=" + maxChargingWattage + "}";
1312 }
Jim Miller16464b82011-10-20 21:10:13 -07001313 }
1314
Lucas Dupin3d053532019-01-29 12:35:22 -08001315 public static class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
1316 private final Consumer<Integer> mStrongAuthRequiredChangedCallback;
1317
1318 public StrongAuthTracker(Context context,
1319 Consumer<Integer> strongAuthRequiredChangedCallback) {
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001320 super(context);
Lucas Dupin3d053532019-01-29 12:35:22 -08001321 mStrongAuthRequiredChangedCallback = strongAuthRequiredChangedCallback;
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001322 }
Adrian Roosb5e47222015-08-14 15:53:06 -07001323
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001324 public boolean isUnlockingWithBiometricAllowed() {
Adrian Roosb5e47222015-08-14 15:53:06 -07001325 int userId = getCurrentUser();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001326 return isBiometricAllowedForUser(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -07001327 }
1328
1329 public boolean hasUserAuthenticatedSinceBoot() {
1330 int userId = getCurrentUser();
1331 return (getStrongAuthForUser(userId)
1332 & STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
1333 }
1334
1335 @Override
1336 public void onStrongAuthRequiredChanged(int userId) {
Lucas Dupin3d053532019-01-29 12:35:22 -08001337 mStrongAuthRequiredChangedCallback.accept(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -07001338 }
1339 }
1340
Jim Millerdcb3d842012-08-23 19:18:12 -07001341 public static KeyguardUpdateMonitor getInstance(Context context) {
1342 if (sInstance == null) {
1343 sInstance = new KeyguardUpdateMonitor(context);
1344 }
1345 return sInstance;
1346 }
1347
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001348 protected void handleStartedWakingUp() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001349 Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001350 updateBiometricListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001351 final int count = mCallbacks.size();
1352 for (int i = 0; i < count; i++) {
1353 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1354 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001355 cb.onStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -07001356 }
1357 }
Nick Desaulniers1d396752016-07-25 15:05:33 -07001358 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -07001359 }
1360
Jorim Jaggi95e40382015-09-16 15:53:42 -07001361 protected void handleStartedGoingToSleep(int arg1) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001362 clearBiometricRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -07001363 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 Jaggi95e40382015-09-16 15:53:42 -07001367 cb.onStartedGoingToSleep(arg1);
1368 }
1369 }
1370 mGoingToSleep = true;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001371 updateBiometricListeningState();
Jorim Jaggi95e40382015-09-16 15:53:42 -07001372 }
1373
1374 protected void handleFinishedGoingToSleep(int arg1) {
1375 mGoingToSleep = false;
1376 final int count = mCallbacks.size();
1377 for (int i = 0; i < count; i++) {
1378 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1379 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001380 cb.onFinishedGoingToSleep(arg1);
Jim Miller20daffd2013-10-07 14:59:53 -07001381 }
1382 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001383 updateBiometricListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001384 }
1385
Jorim Jaggif1518da2015-07-30 11:56:36 -07001386 private void handleScreenTurnedOn() {
1387 final int count = mCallbacks.size();
1388 for (int i = 0; i < count; i++) {
1389 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1390 if (cb != null) {
1391 cb.onScreenTurnedOn();
1392 }
1393 }
1394 }
1395
1396 private void handleScreenTurnedOff() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001397 mHardwareFingerprintUnavailableRetryCount = 0;
1398 mHardwareFaceUnavailableRetryCount = 0;
Jorim Jaggif1518da2015-07-30 11:56:36 -07001399 final int count = mCallbacks.size();
1400 for (int i = 0; i < count; i++) {
1401 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1402 if (cb != null) {
1403 cb.onScreenTurnedOff();
1404 }
1405 }
1406 }
1407
Selim Cinek99415392016-09-09 14:58:41 -07001408 private void handleDreamingStateChanged(int dreamStart) {
1409 final int count = mCallbacks.size();
Kevin Chyn36778ff2017-09-07 19:55:38 -07001410 mIsDreaming = dreamStart == 1;
Selim Cinek99415392016-09-09 14:58:41 -07001411 for (int i = 0; i < count; i++) {
1412 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1413 if (cb != null) {
Kevin Chyn36778ff2017-09-07 19:55:38 -07001414 cb.onDreamingStateChanged(mIsDreaming);
Selim Cinek99415392016-09-09 14:58:41 -07001415 }
1416 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001417 updateBiometricListeningState();
Selim Cinek99415392016-09-09 14:58:41 -07001418 }
1419
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001420 private void handleUserInfoChanged(int userId) {
1421 for (int i = 0; i < mCallbacks.size(); i++) {
1422 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1423 if (cb != null) {
1424 cb.onUserInfoChanged(userId);
1425 }
1426 }
1427 }
1428
Jorim Jaggidadafd42016-09-30 07:20:25 -07001429 private void handleUserUnlocked() {
1430 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1431 for (int i = 0; i < mCallbacks.size(); i++) {
1432 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1433 if (cb != null) {
1434 cb.onUserUnlocked();
1435 }
1436 }
1437 }
1438
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001439 @VisibleForTesting
1440 protected KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001441 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -08001442 mSubscriptionManager = SubscriptionManager.from(context);
Michael Jurkafff56142012-11-28 16:51:00 -08001443 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Lucas Dupin3d053532019-01-29 12:35:22 -08001444 mStrongAuthTracker = new StrongAuthTracker(context, this::notifyStrongAuthStateChanged);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001445
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001446 // Since device can't be un-provisioned, we only need to register a content observer
1447 // to update mDeviceProvisioned when we are...
1448 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001449 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001450 }
Jim Miller47088bb2009-11-24 00:40:16 -08001451
Jim Millerbbf1a742012-07-17 18:30:30 -07001452 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Adrian Roos7b043112015-07-10 13:00:33 -07001453 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001454
Jim Millerbbf1a742012-07-17 18:30:30 -07001455 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001456 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001457 filter.addAction(Intent.ACTION_TIME_TICK);
1458 filter.addAction(Intent.ACTION_TIME_CHANGED);
1459 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
1460 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Jason Monk052082c2015-06-11 11:35:23 -04001461 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001462 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Etan Cohen47051d82015-07-06 16:19:04 -07001463 filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -08001464 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -08001465 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Alex Chauff7653d2018-02-01 17:18:08 +00001466 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jason Monk7bb59302018-05-10 19:38:18 -07001467 context.registerReceiver(mBroadcastReceiver, filter, null, mHandler);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001468
Adam Cohenc276e822012-11-08 13:01:08 -08001469 final IntentFilter bootCompleteFilter = new IntentFilter();
1470 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1471 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
Jason Monk7bb59302018-05-10 19:38:18 -07001472 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter, null, mHandler);
Adam Cohenc276e822012-11-08 13:01:08 -08001473
Adrian Roos48c796c2014-09-01 14:59:23 +02001474 final IntentFilter allUserFilter = new IntentFilter();
1475 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
1476 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
1477 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
1478 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
1479 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001480 allUserFilter.addAction(ACTION_USER_UNLOCKED);
Adrian Roos48c796c2014-09-01 14:59:23 +02001481 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Jason Monk7bb59302018-05-10 19:38:18 -07001482 null, mHandler);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001483
Wink Saville071743f2015-01-12 17:11:04 -08001484 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001485 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001486 ActivityManager.getService().registerUserSwitchObserver(
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001487 new UserSwitchObserver() {
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001488 @Override
1489 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001490 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001491 newUserId, 0, reply));
1492 }
1493 @Override
1494 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001495 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +02001496 newUserId, 0));
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001497 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001498 }, TAG);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001499 } catch (RemoteException e) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001500 e.rethrowAsRuntimeException();
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001501 }
Adrian Roos46842d92014-03-27 14:58:03 +01001502
Jorim Jaggi237b0612015-05-01 14:28:49 -07001503 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
1504 mTrustManager.registerTrustListener(this);
Michal Karpinskic52f8672016-11-18 11:32:45 +00001505 mLockPatternUtils = new LockPatternUtils(context);
1506 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Jim Millerf41fc962014-06-18 16:33:51 -07001507
Kevin Chyn36778ff2017-09-07 19:55:38 -07001508 mDreamManager = IDreamManager.Stub.asInterface(
1509 ServiceManager.getService(DreamService.DREAM_SERVICE));
1510
Jorim Jaggi3f124262016-11-22 13:45:17 +01001511 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
1512 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
1513 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001514 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
Kevin Chynb7b54a62018-09-28 18:48:12 -07001515 mFaceManager = (FaceManager) context.getSystemService(Context.FACE_SERVICE);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001516 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07001517
1518 if (mFpm != null || mFaceManager != null) {
1519 mBiometricManager = context.getSystemService(BiometricManager.class);
1520 mBiometricManager.registerEnabledOnKeyguardCallback(mBiometricEnabledCallback);
1521 }
1522
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001523 updateBiometricListeningState();
Jorim Jaggi3a464782015-08-28 16:59:13 -07001524 if (mFpm != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001525 mFpm.addLockoutResetCallback(mFingerprintLockoutResetCallback);
1526 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07001527 if (mFaceManager != null) {
1528 mFaceManager.addLockoutResetCallback(mFaceLockoutResetCallback);
Jorim Jaggi3a464782015-08-28 16:59:13 -07001529 }
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001530
Winson Chung2cf6ad82017-11-09 17:36:59 -08001531 ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001532 mUserManager = context.getSystemService(UserManager.class);
Alex Chauff7653d2018-02-01 17:18:08 +00001533 mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
1534 mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
Bill Linef81cbd2018-07-05 17:48:49 +08001535 updateAirplaneModeState();
1536 }
1537
1538 private void updateAirplaneModeState() {
1539 // ACTION_AIRPLANE_MODE_CHANGED do not broadcast if device set AirplaneMode ON and boot
1540 if (!WirelessUtils.isAirplaneModeOn(mContext)
1541 || mHandler.hasMessages(MSG_AIRPLANE_MODE_CHANGED)) {
1542 return;
1543 }
1544 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Jorim Jaggiea657062015-04-28 13:45:11 -07001545 }
1546
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001547 private void updateBiometricListeningState() {
1548 updateFingerprintListeningState();
1549 updateFaceListeningState();
1550 }
1551
Jorim Jaggiea657062015-04-28 13:45:11 -07001552 private void updateFingerprintListeningState() {
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001553 // If this message exists, we should not authenticate again until this message is
1554 // consumed by the handler
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001555 if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001556 return;
1557 }
Kevin Chyn0c45b072017-04-24 16:27:11 -07001558 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
Jorim Jaggiea657062015-04-28 13:45:11 -07001559 boolean shouldListenForFingerprint = shouldListenForFingerprint();
Adrian Roos2aaf9442018-11-20 16:57:33 +01001560 boolean runningOrRestarting = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING
1561 || mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING;
1562 if (runningOrRestarting && !shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001563 stopListeningForFingerprint();
Adrian Roos2aaf9442018-11-20 16:57:33 +01001564 } else if (!runningOrRestarting && shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001565 startListeningForFingerprint();
1566 }
1567 }
1568
Lucas Dupin3d053532019-01-29 12:35:22 -08001569 /**
Lucas Dupine0516d52019-02-05 17:54:06 -05001570 * Called whenever passive authentication is requested or aborted by a sensor.
1571 * @param active If the interrupt started or ended.
Lucas Dupin3d053532019-01-29 12:35:22 -08001572 */
Lucas Dupine0516d52019-02-05 17:54:06 -05001573 public void onAuthInterruptDetected(boolean active) {
1574 if (DEBUG) Log.d(TAG, "onAuthInterruptDetected(" + active + ")");
1575 if (mAuthInterruptActive == active) {
1576 return;
1577 }
1578 mAuthInterruptActive = active;
Lucas Dupin3d053532019-01-29 12:35:22 -08001579 updateFaceListeningState();
1580 }
1581
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001582 private void updateFaceListeningState() {
1583 // If this message exists, we should not authenticate again until this message is
1584 // consumed by the handler
1585 if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
1586 return;
1587 }
1588 mHandler.removeCallbacks(mRetryFaceAuthentication);
1589 boolean shouldListenForFace = shouldListenForFace();
1590 if (mFaceRunningState == BIOMETRIC_STATE_RUNNING && !shouldListenForFace) {
1591 stopListeningForFace();
1592 } else if (mFaceRunningState != BIOMETRIC_STATE_RUNNING
1593 && shouldListenForFace) {
1594 startListeningForFace();
1595 }
1596 }
1597
Kevin Chyn129f60f2017-08-11 17:24:42 -07001598 private boolean shouldListenForFingerprintAssistant() {
1599 return mAssistantVisible && mKeyguardOccluded
1600 && !mUserFingerprintAuthenticated.get(getCurrentUser(), false)
1601 && !mUserHasTrust.get(getCurrentUser(), false);
1602 }
1603
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001604 private boolean shouldListenForFaceAssistant() {
1605 return mAssistantVisible && mKeyguardOccluded
1606 && !mUserFaceAuthenticated.get(getCurrentUser(), false)
1607 && !mUserHasTrust.get(getCurrentUser(), false);
1608 }
1609
Jorim Jaggiea657062015-04-28 13:45:11 -07001610 private boolean shouldListenForFingerprint() {
Kevin Chynf3b8fbd2017-05-03 22:24:31 -07001611 return (mKeyguardIsVisible || !mDeviceInteractive ||
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001612 (mBouncer && !mKeyguardGoingAway) || mGoingToSleep ||
Kevin Chyn36778ff2017-09-07 19:55:38 -07001613 shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming))
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001614 && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser())
Kevin Chyn1123ba72018-10-26 10:34:06 -07001615 && !mKeyguardGoingAway && !mFingerprintLockedOut;
Jim Miller9f0753f2015-03-23 23:59:22 -07001616 }
1617
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001618 private boolean shouldListenForFace() {
Lucas Dupin3d053532019-01-29 12:35:22 -08001619 final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep;
1620 final int user = getCurrentUser();
1621
Lucas Dupine0516d52019-02-05 17:54:06 -05001622 return (mBouncer || mAuthInterruptActive || awakeKeyguard || shouldListenForFaceAssistant())
Lucas Dupin3d053532019-01-29 12:35:22 -08001623 && !mSwitchingUser && !getUserCanSkipBouncer(user) && !isFaceDisabled(user)
1624 && !mKeyguardGoingAway && !mFaceLockedOut && mFaceSettingEnabledForUser
1625 && mUserManager.isUserUnlocked(user);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001626 }
1627
1628
Jim Millerce7eb6d2015-04-03 19:29:13 -07001629 private void startListeningForFingerprint() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001630 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING) {
1631 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001632 return;
1633 }
Adrian Roos2aaf9442018-11-20 16:57:33 +01001634 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1635 // Waiting for restart via handleFingerprintError().
1636 return;
1637 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001638 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -07001639 int userId = ActivityManager.getCurrentUser();
Jorim Jaggi71448a72015-08-18 19:49:04 -07001640 if (isUnlockWithFingerprintPossible(userId)) {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001641 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001642 mFingerprintCancelSignal.cancel();
1643 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001644 mFingerprintCancelSignal = new CancellationSignal();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001645 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mFingerprintAuthenticationCallback,
1646 null, userId);
1647 setFingerprintRunningState(BIOMETRIC_STATE_RUNNING);
1648 }
1649 }
1650
1651 private void startListeningForFace() {
1652 if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING) {
1653 setFaceRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);
1654 return;
1655 }
1656 if (DEBUG) Log.v(TAG, "startListeningForFace()");
1657 int userId = ActivityManager.getCurrentUser();
1658 if (isUnlockWithFacePossible(userId)) {
1659 if (mFaceCancelSignal != null) {
1660 mFaceCancelSignal.cancel();
1661 }
1662 mFaceCancelSignal = new CancellationSignal();
Kevin Chynb7b54a62018-09-28 18:48:12 -07001663 mFaceManager.authenticate(null, mFaceCancelSignal, 0,
Kevin Chyna56dff72018-06-19 18:41:12 -07001664 mFaceAuthenticationCallback, null);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001665 setFaceRunningState(BIOMETRIC_STATE_RUNNING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001666 }
1667 }
1668
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001669 public boolean isUnlockWithFingerprintPossible(int userId) {
Selim Cinek3122fa82015-06-18 01:38:59 -07001670 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
1671 && mFpm.getEnrolledFingerprints(userId).size() > 0;
1672 }
1673
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001674 public boolean isUnlockWithFacePossible(int userId) {
Kevin Chynb7b54a62018-09-28 18:48:12 -07001675 return mFaceManager != null && mFaceManager.isHardwareDetected()
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001676 && !isFaceDisabled(userId)
Kevin Chynb7b54a62018-09-28 18:48:12 -07001677 && mFaceManager.hasEnrolledTemplates(userId);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001678 }
1679
Jorim Jaggiea657062015-04-28 13:45:11 -07001680 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001681 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001682 if (mFingerprintRunningState == BIOMETRIC_STATE_RUNNING) {
Kevin Chyn2fefd462017-04-28 12:18:19 -07001683 if (mFingerprintCancelSignal != null) {
1684 mFingerprintCancelSignal.cancel();
1685 mFingerprintCancelSignal = null;
1686 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001687 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001688 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001689 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1690 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING);
1691 }
1692 }
1693
1694 private void stopListeningForFace() {
1695 if (DEBUG) Log.v(TAG, "stopListeningForFace()");
1696 if (mFaceRunningState == BIOMETRIC_STATE_RUNNING) {
1697 if (mFaceCancelSignal != null) {
1698 mFaceCancelSignal.cancel();
1699 mFaceCancelSignal = null;
1700 }
1701 setFaceRunningState(BIOMETRIC_STATE_CANCELLING);
1702 }
1703 if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1704 setFaceRunningState(BIOMETRIC_STATE_CANCELLING);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001705 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001706 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001707
Michael Jurkafff56142012-11-28 16:51:00 -08001708 private boolean isDeviceProvisionedInSettingsDb() {
1709 return Settings.Global.getInt(mContext.getContentResolver(),
1710 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1711 }
1712
Jim Millerbbf1a742012-07-17 18:30:30 -07001713 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -08001714 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001715 @Override
1716 public void onChange(boolean selfChange) {
1717 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -08001718 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001719 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001720 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001721 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001722 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001723 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001724 };
1725
1726 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -07001727 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -08001728 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -07001729
1730 // prevent a race condition between where we check the flag and where we register the
1731 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -08001732 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001733 if (provisioned != mDeviceProvisioned) {
1734 mDeviceProvisioned = provisioned;
1735 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001736 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001737 }
1738 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001739 }
1740
Jim Millerbbf1a742012-07-17 18:30:30 -07001741 /**
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001742 * Update the state whether Keyguard currently has a lockscreen wallpaper.
1743 *
1744 * @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper.
1745 */
1746 public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001747 checkIsHandlerThread();
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001748 if (hasLockscreenWallpaper != mHasLockscreenWallpaper) {
1749 mHasLockscreenWallpaper = hasLockscreenWallpaper;
1750 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1751 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1752 if (cb != null) {
1753 cb.onHasLockscreenWallpaperChanged(hasLockscreenWallpaper);
1754 }
1755 }
1756 }
1757 }
1758
1759 /**
1760 * @return Whether Keyguard has a lockscreen wallpaper.
1761 */
1762 public boolean hasLockscreenWallpaper() {
1763 return mHasLockscreenWallpaper;
1764 }
1765
1766 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001767 * Handle {@link #MSG_DPM_STATE_CHANGED}
1768 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001769 private void handleDevicePolicyManagerStateChanged() {
Adrian Roos733b6632015-08-21 14:32:35 -07001770 updateFingerprintListeningState();
Jim Millerdcb3d842012-08-23 19:18:12 -07001771 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1772 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1773 if (cb != null) {
1774 cb.onDevicePolicyManagerStateChanged();
1775 }
Jim Millerb0304762012-03-13 20:01:25 -07001776 }
1777 }
1778
Jim Millerbbf1a742012-07-17 18:30:30 -07001779 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001780 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -07001781 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001782 private void handleUserSwitching(int userId, IRemoteCallback reply) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001783 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001784 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1785 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001786 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -07001787 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001788 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001789 try {
1790 reply.sendResult(null);
1791 } catch (RemoteException e) {
1792 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001793 }
1794
Jim Millerbbf1a742012-07-17 18:30:30 -07001795 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001796 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
1797 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001798 private void handleUserSwitchComplete(int userId) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001799 for (int i = 0; i < mCallbacks.size(); i++) {
1800 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1801 if (cb != null) {
1802 cb.onUserSwitchComplete(userId);
1803 }
1804 }
1805 }
1806
1807 /**
Jim Miller90873d52013-09-26 18:11:38 -07001808 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
1809 * keyguard crashes sometime after boot, then it will never receive this
1810 * broadcast and hence not handle the event. This method is ultimately called by
1811 * PhoneWindowManager in this case.
1812 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001813 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001814 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -07001815 }
1816
1817 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001818 * Handle {@link #MSG_BOOT_COMPLETED}
1819 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001820 private void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001821 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001822 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001823 for (int i = 0; i < mCallbacks.size(); i++) {
1824 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1825 if (cb != null) {
1826 cb.onBootCompleted();
1827 }
1828 }
1829 }
1830
1831 /**
Jim Miller5ecd8112013-01-09 18:50:26 -08001832 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001833 * destroyed.
1834 */
1835 public boolean hasBootCompleted() {
1836 return mBootCompleted;
1837 }
1838
1839 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001840 * Handle {@link #MSG_DEVICE_PROVISIONED}
1841 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001842 private void handleDeviceProvisioned() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001843 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001844 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1845 if (cb != null) {
1846 cb.onDeviceProvisioned();
1847 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001848 }
Michael Jurkafff56142012-11-28 16:51:00 -08001849 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001850 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -08001851 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
1852 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001853 }
1854 }
1855
Jim Millerbbf1a742012-07-17 18:30:30 -07001856 /**
1857 * Handle {@link #MSG_PHONE_STATE_CHANGED}
1858 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001859 private void handlePhoneStateChanged(String newState) {
Jim Millerc23024d2010-02-24 15:37:00 -08001860 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001861 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
1862 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
1863 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
1864 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
1865 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
1866 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
1867 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001868 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001869 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1870 if (cb != null) {
1871 cb.onPhoneStateChanged(mPhoneState);
1872 }
Jim Millerc23024d2010-02-24 15:37:00 -08001873 }
1874 }
1875
Jim Millerbbf1a742012-07-17 18:30:30 -07001876 /**
1877 * Handle {@link #MSG_RINGER_MODE_CHANGED}
1878 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001879 private void handleRingerModeChange(int mode) {
Jim Miller47088bb2009-11-24 00:40:16 -08001880 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001881 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -07001882 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001883 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1884 if (cb != null) {
1885 cb.onRingerModeChanged(mode);
1886 }
Jim Miller47088bb2009-11-24 00:40:16 -08001887 }
1888 }
1889
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001890 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001891 * Handle {@link #MSG_TIME_UPDATE}
1892 */
1893 private void handleTimeUpdate() {
1894 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001895 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001896 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1897 if (cb != null) {
1898 cb.onTimeChanged();
1899 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001900 }
1901 }
1902
1903 /**
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05001904 * Handle (@line #MSG_TIMEZONE_UPDATE}
1905 */
1906 private void handleTimeZoneUpdate(String timeZone) {
1907 if (DEBUG) Log.d(TAG, "handleTimeZoneUpdate");
1908 for (int i = 0; i < mCallbacks.size(); i++) {
1909 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1910 if (cb != null) {
1911 cb.onTimeZoneChanged(TimeZone.getTimeZone(timeZone));
1912 // Also notify callbacks about time change to remain compatible.
1913 cb.onTimeChanged();
1914 }
1915 }
1916 }
1917
1918 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001919 * Handle {@link #MSG_BATTERY_UPDATE}
1920 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001921 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001922 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001923 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
1924 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07001925 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001926 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001927 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1928 if (cb != null) {
1929 cb.onRefreshBatteryInfo(status);
1930 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001931 }
1932 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001933 }
1934
1935 /**
Bill Linef81cbd2018-07-05 17:48:49 +08001936 * Handle Telephony status during Boot for CarrierText display policy
1937 */
1938 @VisibleForTesting
1939 void updateTelephonyCapable(boolean capable){
1940 if (capable == mTelephonyCapable) {
1941 return;
1942 }
1943 mTelephonyCapable = capable;
1944 for (WeakReference<KeyguardUpdateMonitorCallback> ref : mCallbacks) {
1945 KeyguardUpdateMonitorCallback cb = ref.get();
1946 if (cb != null) {
1947 cb.onTelephonyCapable(mTelephonyCapable);
1948 }
1949 }
1950 }
1951
1952 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001953 * Handle {@link #MSG_SIM_STATE_CHANGE}
1954 */
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001955 @VisibleForTesting
Adrian Roos30a2ae62018-04-25 19:09:50 +02001956 void handleSimStateChange(int subId, int slotId, State state) {
1957 checkIsHandlerThread();
Jim Miller52a61332014-11-12 19:29:51 -08001958 if (DEBUG_SIM_STATES) {
1959 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
1960 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001961 }
1962
Lucas Dupin2e0d4952018-12-05 20:03:53 -08001963 boolean becameAbsent = false;
Wink Savillea54bf652014-12-11 13:37:50 -08001964 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08001965 Log.w(TAG, "invalid subId in handleSimStateChange()");
Bill Linef81cbd2018-07-05 17:48:49 +08001966 /* Only handle No SIM(ABSENT) due to handleServiceStateChange() handle other case */
1967 if (state == State.ABSENT) {
1968 updateTelephonyCapable(true);
Lucas Dupin2e0d4952018-12-05 20:03:53 -08001969 // Even though the subscription is not valid anymore, we need to notify that the
1970 // SIM card was removed so we can update the UI.
1971 becameAbsent = true;
Brad Ebingere6c6f722018-12-20 21:11:44 -08001972 for (SimData data : mSimDatas.values()) {
1973 // Set the SIM state of all SimData associated with that slot to ABSENT se we
1974 // do not move back into PIN/PUK locked and not detect the change below.
1975 if (data.slotId == slotId) {
1976 data.simState = State.ABSENT;
1977 }
1978 }
Lucas Dupin2e0d4952018-12-05 20:03:53 -08001979 } else {
1980 return;
Bill Linef81cbd2018-07-05 17:48:49 +08001981 }
Jim Miller52a61332014-11-12 19:29:51 -08001982 }
1983
1984 SimData data = mSimDatas.get(subId);
1985 final boolean changed;
1986 if (data == null) {
1987 data = new SimData(state, slotId, subId);
1988 mSimDatas.put(subId, data);
1989 changed = true; // no data yet; force update
1990 } else {
1991 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
1992 data.simState = state;
1993 data.subId = subId;
1994 data.slotId = slotId;
1995 }
Lucas Dupin2e0d4952018-12-05 20:03:53 -08001996 if ((changed || becameAbsent) && state != State.UNKNOWN) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001997 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001998 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1999 if (cb != null) {
Jim Miller52a61332014-11-12 19:29:51 -08002000 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07002001 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002002 }
2003 }
2004 }
2005
Jim Millerbbf1a742012-07-17 18:30:30 -07002006 /**
Etan Cohen47051d82015-07-06 16:19:04 -07002007 * Handle {@link #MSG_SERVICE_STATE_CHANGE}
2008 */
Bill Linef81cbd2018-07-05 17:48:49 +08002009 @VisibleForTesting
2010 void handleServiceStateChange(int subId, ServiceState serviceState) {
Etan Cohen47051d82015-07-06 16:19:04 -07002011 if (DEBUG) {
2012 Log.d(TAG,
2013 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
2014 }
2015
2016 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2017 Log.w(TAG, "invalid subId in handleServiceStateChange()");
2018 return;
Bill Linef81cbd2018-07-05 17:48:49 +08002019 } else {
2020 updateTelephonyCapable(true);
Etan Cohen47051d82015-07-06 16:19:04 -07002021 }
2022
2023 mServiceStates.put(subId, serviceState);
2024
2025 for (int j = 0; j < mCallbacks.size(); j++) {
2026 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
2027 if (cb != null) {
2028 cb.onRefreshCarrierInfo();
2029 }
2030 }
2031 }
2032
Lucas Dupinf8463ee2018-06-11 16:18:15 -07002033 public boolean isKeyguardVisible() {
2034 return mKeyguardIsVisible;
2035 }
2036
Etan Cohen47051d82015-07-06 16:19:04 -07002037 /**
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002038 * Notifies that the visibility state of Keyguard has changed.
2039 *
2040 * <p>Needs to be called from the main thread.
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002041 */
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002042 public void onKeyguardVisibilityChanged(boolean showing) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002043 checkIsHandlerThread();
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002044 if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
2045 mKeyguardIsVisible = showing;
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002046 for (int i = 0; i < mCallbacks.size(); i++) {
2047 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2048 if (cb != null) {
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002049 cb.onKeyguardVisibilityChangedRaw(showing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002050 }
2051 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002052 updateBiometricListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002053 }
2054
Brian Colonna7fce3802013-09-17 15:51:32 -04002055 /**
Selim Cinek1fcafc42015-07-20 14:39:25 -07002056 * Handle {@link #MSG_KEYGUARD_RESET}
2057 */
2058 private void handleKeyguardReset() {
2059 if (DEBUG) Log.d(TAG, "handleKeyguardReset");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002060 updateBiometricListeningState();
Jorim Jaggi031f7952016-09-01 16:39:26 -07002061 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
2062 }
2063
2064 private boolean resolveNeedsSlowUnlockTransition() {
2065 if (mUserManager.isUserUnlocked(getCurrentUser())) {
2066 return false;
2067 }
2068 Intent homeIntent = new Intent(Intent.ACTION_MAIN)
2069 .addCategory(Intent.CATEGORY_HOME);
2070 ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(homeIntent,
2071 0 /* flags */);
2072 return FALLBACK_HOME_COMPONENT.equals(resolveInfo.getComponentInfo().getComponentName());
Selim Cinek1fcafc42015-07-20 14:39:25 -07002073 }
2074
2075 /**
Adrian Roosb6011622014-05-14 15:52:53 +02002076 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
2077 * @see #sendKeyguardBouncerChanged(boolean)
2078 */
2079 private void handleKeyguardBouncerChanged(int bouncer) {
2080 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
2081 boolean isBouncer = (bouncer == 1);
2082 mBouncer = isBouncer;
2083 for (int i = 0; i < mCallbacks.size(); i++) {
2084 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2085 if (cb != null) {
2086 cb.onKeyguardBouncerChanged(isBouncer);
2087 }
2088 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002089 updateBiometricListeningState();
Adrian Roosb6011622014-05-14 15:52:53 +02002090 }
2091
2092 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04002093 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
2094 */
2095 private void handleReportEmergencyCallAction() {
2096 for (int i = 0; i < mCallbacks.size(); i++) {
2097 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2098 if (cb != null) {
2099 cb.onEmergencyCallAction();
2100 }
2101 }
2102 }
2103
Lucas Dupin4272f442018-01-13 22:00:35 -08002104 private boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002105 final boolean nowPluggedIn = current.isPluggedIn();
2106 final boolean wasPluggedIn = old.isPluggedIn();
Lucas Dupin4272f442018-01-13 22:00:35 -08002107 final boolean stateChangedWhilePluggedIn = wasPluggedIn && nowPluggedIn
Jim Miller16464b82011-10-20 21:10:13 -07002108 && (old.status != current.status);
2109
2110 // change in plug state is always interesting
2111 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002112 return true;
2113 }
2114
Lucas Dupin3fcdd472018-01-19 19:06:45 -08002115 // change in battery level
2116 if (old.level != current.level) {
Jim Miller16464b82011-10-20 21:10:13 -07002117 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002118 }
Adrian Roos76dc5a52015-07-21 16:20:36 -07002119
2120 // change in charging current while plugged in
Adrian Roos0c859ae2015-11-23 16:47:50 -08002121 if (nowPluggedIn && current.maxChargingWattage != old.maxChargingWattage) {
Adrian Roos76dc5a52015-07-21 16:20:36 -07002122 return true;
2123 }
2124
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002125 return false;
2126 }
2127
2128 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07002129 * Remove the given observer's callback.
2130 *
Jim Miller6212cc02012-09-05 17:35:31 -07002131 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002132 */
Jim Miller6212cc02012-09-05 17:35:31 -07002133 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002134 checkIsHandlerThread();
Jim Miller6212cc02012-09-05 17:35:31 -07002135 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
2136 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
2137 if (mCallbacks.get(i).get() == callback) {
2138 mCallbacks.remove(i);
2139 }
2140 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002141 }
2142
2143 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002144 * Register to receive notifications about general keyguard information
2145 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07002146 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002147 */
Jim Millerbbf1a742012-07-17 18:30:30 -07002148 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002149 checkIsHandlerThread();
Jim Miller6212cc02012-09-05 17:35:31 -07002150 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
2151 // Prevent adding duplicate callbacks
2152 for (int i = 0; i < mCallbacks.size(); i++) {
2153 if (mCallbacks.get(i).get() == callback) {
2154 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
2155 new Exception("Called by"));
2156 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07002157 }
2158 }
Jim Miller6212cc02012-09-05 17:35:31 -07002159 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
2160 removeCallback(null); // remove unused references
2161 sendUpdates(callback);
2162 }
2163
Evan Rosky18396452016-07-27 15:19:37 -07002164 public boolean isSwitchingUser() {
2165 return mSwitchingUser;
2166 }
2167
Adrian Roos30a2ae62018-04-25 19:09:50 +02002168 @AnyThread
Evan Rosky18396452016-07-27 15:19:37 -07002169 public void setSwitchingUser(boolean switching) {
2170 mSwitchingUser = switching;
Selim Cinekbbe19242017-12-08 15:42:08 -08002171 // Since this comes in on a binder thread, we need to post if first
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002172 mHandler.post(mUpdateBiometricListeningState);
Evan Rosky18396452016-07-27 15:19:37 -07002173 }
2174
Jim Miller6212cc02012-09-05 17:35:31 -07002175 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
2176 // Notify listener of the current state
2177 callback.onRefreshBatteryInfo(mBatteryStatus);
2178 callback.onTimeChanged();
2179 callback.onRingerModeChanged(mRingMode);
2180 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05002181 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07002182 callback.onClockVisibilityChanged();
Lucas Dupin16cfe452018-02-08 13:14:50 -08002183 callback.onKeyguardVisibilityChangedRaw(mKeyguardIsVisible);
Bill Linef81cbd2018-07-05 17:48:49 +08002184 callback.onTelephonyCapable(mTelephonyCapable);
Jim Miller52a61332014-11-12 19:29:51 -08002185 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
2186 final SimData state = data.getValue();
2187 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
2188 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002189 }
2190
Selim Cinek1fcafc42015-07-20 14:39:25 -07002191 public void sendKeyguardReset() {
2192 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
2193 }
2194
Adrian Roosb6011622014-05-14 15:52:53 +02002195 /**
2196 * @see #handleKeyguardBouncerChanged(int)
2197 */
2198 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
2199 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
2200 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
2201 message.arg1 = showingBouncer ? 1 : 0;
2202 message.sendToTarget();
2203 }
2204
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002205 /**
Jim Miller90d5d462011-11-17 16:57:01 -08002206 * 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 -08002207 * have the information earlier than waiting for the intent
2208 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08002209 *
2210 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
2211 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002212 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02002213 @MainThread
Jim Miller52a61332014-11-12 19:29:51 -08002214 public void reportSimUnlocked(int subId) {
2215 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
Sanket Padawe7e460252017-03-10 16:18:20 -08002216 int slotId = SubscriptionManager.getSlotIndex(subId);
Jim Miller52a61332014-11-12 19:29:51 -08002217 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002218 }
2219
Brian Colonna7fce3802013-09-17 15:51:32 -04002220 /**
2221 * Report that the emergency call button has been pressed and the emergency dialer is
2222 * about to be displayed.
2223 *
2224 * @param bypassHandler runs immediately.
2225 *
2226 * NOTE: Must be called from UI thread if bypassHandler == true.
2227 */
2228 public void reportEmergencyCallAction(boolean bypassHandler) {
2229 if (!bypassHandler) {
2230 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
2231 } else {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002232 checkIsHandlerThread();
Brian Colonna7fce3802013-09-17 15:51:32 -04002233 handleReportEmergencyCallAction();
2234 }
2235 }
2236
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002237 /**
2238 * @return Whether the device is provisioned (whether they have gone through
2239 * the setup wizard)
2240 */
2241 public boolean isDeviceProvisioned() {
2242 return mDeviceProvisioned;
2243 }
2244
Kensuke Matsui21d1bf12017-03-14 13:27:20 +09002245 public ServiceState getServiceState(int subId) {
2246 return mServiceStates.get(subId);
2247 }
2248
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002249 public void clearBiometricRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07002250 mUserFingerprintAuthenticated.clear();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002251 mUserFaceAuthenticated.clear();
2252 mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FINGERPRINT);
2253 mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FACE);
Jim Millerf41fc962014-06-18 16:33:51 -07002254 }
2255
Jim Miller52a61332014-11-12 19:29:51 -08002256 public boolean isSimPinVoiceSecure() {
2257 // TODO: only count SIMs that handle voice
2258 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07002259 }
2260
2261 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08002262 // True if any SIM is pin secure
2263 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
2264 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
2265 }
2266 return false;
2267 }
2268
Jason Monk9ff69bd2014-12-02 16:43:17 -05002269 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08002270 if (mSimDatas.containsKey(subId)) {
2271 return mSimDatas.get(subId).simState;
2272 } else {
2273 return State.UNKNOWN;
2274 }
2275 }
2276
Winson Chung67f5c8b2018-09-24 12:09:19 -07002277 private final TaskStackChangeListener
2278 mTaskStackListener = new TaskStackChangeListener() {
Kevin Chyn2fefd462017-04-28 12:18:19 -07002279 @Override
2280 public void onTaskStackChangedBackground() {
2281 try {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002282 ActivityManager.StackInfo info = ActivityTaskManager.getService().getStackInfo(
Wale Ogunwale68278562017-09-23 17:13:55 -07002283 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
Kevin Chyn2fefd462017-04-28 12:18:19 -07002284 if (info == null) {
2285 return;
2286 }
2287 mHandler.sendMessage(mHandler.obtainMessage(MSG_ASSISTANT_STACK_CHANGED,
2288 info.visible));
2289 } catch (RemoteException e) {
2290 Log.e(TAG, "unable to check task stack", e);
2291 }
2292 }
2293 };
2294
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002295 /**
Richard Choue0381b82018-04-24 03:48:59 +00002296 * @return true if and only if the state has changed for the specified {@code slotId}
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002297 */
Richard Choue0381b82018-04-24 03:48:59 +00002298 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08002299
2300 // This is awful. It exists because there are two APIs for getting the SIM status
2301 // that don't return the complete set of values and have different types. In Keyguard we
2302 // need IccCardConstants, but TelephonyManager would only give us
2303 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08002304 final TelephonyManager tele = TelephonyManager.from(mContext);
Richard Choue0381b82018-04-24 03:48:59 +00002305 int simState = tele.getSimState(slotId);
2306 State state;
2307 try {
2308 state = State.intToState(simState);
2309 } catch(IllegalArgumentException ex) {
2310 Log.w(TAG, "Unknown sim state: " + simState);
2311 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05002312 }
Richard Choue0381b82018-04-24 03:48:59 +00002313 SimData data = mSimDatas.get(subId);
2314 final boolean changed;
2315 if (data == null) {
2316 data = new SimData(state, slotId, subId);
2317 mSimDatas.put(subId, data);
2318 changed = true; // no data yet; force update
2319 } else {
2320 changed = data.simState != state;
2321 data.simState = state;
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002322 }
Richard Choue0381b82018-04-24 03:48:59 +00002323 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07002324 }
2325
2326 public static boolean isSimPinSecure(IccCardConstants.State state) {
2327 final IccCardConstants.State simState = state;
2328 return (simState == IccCardConstants.State.PIN_REQUIRED
2329 || simState == IccCardConstants.State.PUK_REQUIRED
2330 || simState == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07002331 }
Jim Miller8f09fd22013-03-14 19:04:28 -07002332
2333 public DisplayClientState getCachedDisplayClientState() {
2334 return mDisplayClientState;
2335 }
Jim Miller20daffd2013-10-07 14:59:53 -07002336
2337 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
2338 // (KeyguardViewMediator, KeyguardHostView)
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002339 public void dispatchStartedWakingUp() {
2340 synchronized (this) {
2341 mDeviceInteractive = true;
2342 }
2343 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
2344 }
2345
Jorim Jaggi95e40382015-09-16 15:53:42 -07002346 public void dispatchStartedGoingToSleep(int why) {
2347 mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
2348 }
2349
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002350 public void dispatchFinishedGoingToSleep(int why) {
2351 synchronized(this) {
2352 mDeviceInteractive = false;
2353 }
2354 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
2355 }
2356
Jim Miller20daffd2013-10-07 14:59:53 -07002357 public void dispatchScreenTurnedOn() {
2358 synchronized (this) {
2359 mScreenOn = true;
2360 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07002361 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
Jim Miller20daffd2013-10-07 14:59:53 -07002362 }
2363
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002364 public void dispatchScreenTurnedOff() {
Jim Miller20daffd2013-10-07 14:59:53 -07002365 synchronized(this) {
2366 mScreenOn = false;
2367 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07002368 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
Jim Miller20daffd2013-10-07 14:59:53 -07002369 }
2370
Selim Cinek99415392016-09-09 14:58:41 -07002371 public void dispatchDreamingStarted() {
2372 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 1, 0));
2373 }
2374
2375 public void dispatchDreamingStopped() {
2376 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 0, 0));
2377 }
2378
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002379 public boolean isDeviceInteractive() {
2380 return mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -07002381 }
Jim Miller52a61332014-11-12 19:29:51 -08002382
Jorim Jaggi95e40382015-09-16 15:53:42 -07002383 public boolean isGoingToSleep() {
2384 return mGoingToSleep;
2385 }
2386
Jim Miller52a61332014-11-12 19:29:51 -08002387 /**
2388 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
2389 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08002390 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08002391 */
2392 public int getNextSubIdForState(State state) {
2393 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08002394 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08002395 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
2396 for (int i = 0; i < list.size(); i++) {
2397 final SubscriptionInfo info = list.get(i);
2398 final int id = info.getSubscriptionId();
Sanket Padawe7e460252017-03-10 16:18:20 -08002399 int slotId = SubscriptionManager.getSlotIndex(id);
Jim Miller52a61332014-11-12 19:29:51 -08002400 if (state == getSimState(id) && bestSlotId > slotId ) {
2401 resultId = id;
2402 bestSlotId = slotId;
2403 }
2404 }
2405 return resultId;
2406 }
2407
2408 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
2409 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
2410 for (int i = 0; i < list.size(); i++) {
2411 SubscriptionInfo info = list.get(i);
2412 if (subId == info.getSubscriptionId()) return info;
2413 }
2414 return null; // not found
2415 }
Jason Monkab525272015-07-13 17:02:49 -04002416
Alex Chauff7653d2018-02-01 17:18:08 +00002417 /**
2418 * @return a cached version of DevicePolicyManager.isLogoutEnabled()
2419 */
2420 public boolean isLogoutEnabled() {
2421 return mLogoutEnabled;
2422 }
2423
2424 private void updateLogoutEnabled() {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002425 checkIsHandlerThread();
Alex Chauff7653d2018-02-01 17:18:08 +00002426 boolean logoutEnabled = mDevicePolicyManager.isLogoutEnabled();
2427 if (mLogoutEnabled != logoutEnabled) {
2428 mLogoutEnabled = logoutEnabled;
2429 for (int i = 0; i < mCallbacks.size(); i++) {
2430 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2431 if (cb != null) {
2432 cb.onLogoutEnabledChanged();
2433 }
2434 }
2435 }
2436 }
2437
Adrian Roos30a2ae62018-04-25 19:09:50 +02002438 private void checkIsHandlerThread() {
2439 if (sDisableHandlerCheckForTesting) {
2440 return;
2441 }
2442 if (!mHandler.getLooper().isCurrentThread()) {
2443 Log.wtf(TAG, "must call on mHandler's thread "
2444 + mHandler.getLooper().getThread() + ", not " + Thread.currentThread());
2445 }
2446 }
2447
2448 /**
2449 * Turn off the handler check for testing.
2450 *
2451 * This is necessary because currently tests are not too careful about which thread they call
2452 * into this class on.
2453 *
2454 * Note that this must be called before scheduling any work involving KeyguardUpdateMonitor
2455 * instances.
2456 *
2457 * TODO: fix the tests and remove this.
2458 */
2459 @VisibleForTesting
2460 public static void disableHandlerCheckForTesting(Instrumentation instrumentation) {
2461 Preconditions.checkNotNull(instrumentation, "Must only call this method in tests!");
2462 // Don't need synchronization here *if* the callers follow the contract and call this only
2463 // before scheduling work for KeyguardUpdateMonitor on other threads, because the scheduling
2464 // of that work forces a happens-before relationship.
2465 sDisableHandlerCheckForTesting = true;
2466 }
2467
Jason Monkab525272015-07-13 17:02:49 -04002468 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2469 pw.println("KeyguardUpdateMonitor state:");
2470 pw.println(" SIM States:");
2471 for (SimData data : mSimDatas.values()) {
2472 pw.println(" " + data.toString());
2473 }
2474 pw.println(" Subs:");
2475 if (mSubscriptionInfo != null) {
2476 for (int i = 0; i < mSubscriptionInfo.size(); i++) {
2477 pw.println(" " + mSubscriptionInfo.get(i));
2478 }
2479 }
2480 pw.println(" Service states:");
2481 for (int subId : mServiceStates.keySet()) {
2482 pw.println(" " + subId + "=" + mServiceStates.get(subId));
2483 }
Jim Millerd72d5ac2015-09-29 18:55:32 -07002484 if (mFpm != null && mFpm.isHardwareDetected()) {
2485 final int userId = ActivityManager.getCurrentUser();
2486 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
2487 pw.println(" Fingerprint state (user=" + userId + ")");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002488 pw.println(" allowed=" + isUnlockingWithBiometricAllowed());
Jim Millerd72d5ac2015-09-29 18:55:32 -07002489 pw.println(" auth'd=" + mUserFingerprintAuthenticated.get(userId));
2490 pw.println(" authSinceBoot="
2491 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
2492 pw.println(" disabled(DPM)=" + isFingerprintDisabled(userId));
2493 pw.println(" possible=" + isUnlockWithFingerprintPossible(userId));
Adrian Roos2aaf9442018-11-20 16:57:33 +01002494 pw.println(" listening: actual=" + mFingerprintRunningState
2495 + " expected=" + (shouldListenForFingerprint() ? 1 : 0));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002496 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002497 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
2498 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07002499 if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002500 final int userId = ActivityManager.getCurrentUser();
2501 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
2502 pw.println(" Face authentication state (user=" + userId + ")");
2503 pw.println(" allowed=" + isUnlockingWithBiometricAllowed());
2504 pw.println(" auth'd=" + mUserFaceAuthenticated.get(userId));
2505 pw.println(" authSinceBoot="
2506 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
2507 pw.println(" disabled(DPM)=" + isFaceDisabled(userId));
2508 pw.println(" possible=" + isUnlockWithFacePossible(userId));
2509 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
2510 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
Kevin Chynb7b54a62018-09-28 18:48:12 -07002511 pw.println(" enabledByUser=" + mFaceSettingEnabledForUser);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002512 }
Jason Monkab525272015-07-13 17:02:49 -04002513 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002514}