blob: 8d858dcb25df31c40c8c7cef7960d7fe832606fb [file] [log] [blame]
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jim Miller5ecd8112013-01-09 18:50:26 -080017package com.android.keyguard;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080018
Wale Ogunwale68278562017-09-23 17:13:55 -070019import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
20import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Jorim Jaggidadafd42016-09-30 07:20:25 -070021import static android.content.Intent.ACTION_USER_UNLOCKED;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070022import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
23import static android.os.BatteryManager.BATTERY_STATUS_FULL;
24import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
25import static android.os.BatteryManager.EXTRA_HEALTH;
26import static android.os.BatteryManager.EXTRA_LEVEL;
27import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
28import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
29import static android.os.BatteryManager.EXTRA_PLUGGED;
30import static android.os.BatteryManager.EXTRA_STATUS;
Fabian Kozynskiccde55d2019-06-26 10:06:09 -040031import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070032
Lucas Dupin8eec2682019-07-01 16:41:17 -070033import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
34import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
35import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
36import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
37import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
38
Adrian Roos30a2ae62018-04-25 19:09:50 +020039import android.annotation.AnyThread;
40import android.annotation.MainThread;
Jorim Jaggiccdfa932015-04-13 16:29:48 -070041import android.app.ActivityManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070042import android.app.ActivityTaskManager;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020043import android.app.AlarmManager;
Adrian Roos30a2ae62018-04-25 19:09:50 +020044import android.app.Instrumentation;
Jim Miller8f09fd22013-03-14 19:04:28 -070045import android.app.PendingIntent;
Sudheer Shanka2c4522c2016-08-27 20:53:28 -070046import android.app.UserSwitchObserver;
Jim Millerb0304762012-03-13 20:01:25 -070047import android.app.admin.DevicePolicyManager;
Adrian Roos46842d92014-03-27 14:58:03 +010048import android.app.trust.TrustManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080049import android.content.BroadcastReceiver;
Jorim Jaggi031f7952016-09-01 16:39:26 -070050import android.content.ComponentName;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080051import android.content.Context;
52import android.content.Intent;
53import android.content.IntentFilter;
Adrian Roosca8a2162017-08-17 19:00:58 +020054import android.content.pm.IPackageManager;
Jorim Jaggi031f7952016-09-01 16:39:26 -070055import android.content.pm.PackageManager;
56import android.content.pm.ResolveInfo;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080057import android.database.ContentObserver;
Kevin Chynb7b54a62018-09-28 18:48:12 -070058import android.hardware.biometrics.BiometricManager;
Kevin Chyn56233ab2018-09-20 17:10:57 -070059import android.hardware.biometrics.BiometricSourceType;
Kevin Chynb7b54a62018-09-28 18:48:12 -070060import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
Gilad Brettercb51b8b2018-03-22 17:04:51 +020061import android.hardware.face.FaceManager;
Jorim Jaggi86bed402015-08-20 18:20:02 -070062import android.hardware.fingerprint.FingerprintManager;
63import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
64import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
Jim Miller47088bb2009-11-24 00:40:16 -080065import android.media.AudioManager;
Jim Miller79a444a2011-02-15 15:02:11 -080066import android.os.BatteryManager;
Jim Miller9f0753f2015-03-23 23:59:22 -070067import android.os.CancellationSignal;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080068import android.os.Handler;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070069import android.os.IRemoteCallback;
Jason Monk7bb59302018-05-10 19:38:18 -070070import android.os.Looper;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080071import android.os.Message;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070072import android.os.RemoteException;
Adrian Roosca8a2162017-08-17 19:00:58 +020073import android.os.ServiceManager;
Nick Desaulniers1d396752016-07-25 15:05:33 -070074import android.os.Trace;
Amith Yamasanie8e93a12013-05-09 18:12:30 -070075import android.os.UserHandle;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070076import android.os.UserManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080077import android.provider.Settings;
Kevin Chyn36778ff2017-09-07 19:55:38 -070078import android.service.dreams.DreamService;
79import android.service.dreams.IDreamManager;
Fabian Kozynskiccde55d2019-06-26 10:06:09 -040080import android.telephony.PhoneStateListener;
Etan Cohen47051d82015-07-06 16:19:04 -070081import android.telephony.ServiceState;
Jim Miller52a61332014-11-12 19:29:51 -080082import android.telephony.SubscriptionInfo;
Jim Miller52a61332014-11-12 19:29:51 -080083import android.telephony.SubscriptionManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -080084import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Jim Millerc23024d2010-02-24 15:37:00 -080085import android.telephony.TelephonyManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080086import android.util.Log;
Adrian Roos46842d92014-03-27 14:58:03 +010087import android.util.SparseBooleanArray;
88
Lucas Dupin7517b5d2017-08-22 12:51:25 -070089import com.android.internal.annotations.VisibleForTesting;
Jorim Jaggi86bed402015-08-20 18:20:02 -070090import com.android.internal.telephony.IccCardConstants;
91import com.android.internal.telephony.IccCardConstants.State;
92import com.android.internal.telephony.PhoneConstants;
93import com.android.internal.telephony.TelephonyIntents;
Adrian Roos30a2ae62018-04-25 19:09:50 +020094import com.android.internal.util.Preconditions;
Adrian Roosb5e47222015-08-14 15:53:06 -070095import com.android.internal.widget.LockPatternUtils;
Bill Linef81cbd2018-07-05 17:48:49 +080096import com.android.settingslib.WirelessUtils;
Sunny Goyal87fccf02019-08-13 17:39:10 -070097import com.android.systemui.R;
Winson Chung2cf6ad82017-11-09 17:36:59 -080098import com.android.systemui.shared.system.ActivityManagerWrapper;
Winson Chung67f5c8b2018-09-24 12:09:19 -070099import com.android.systemui.shared.system.TaskStackChangeListener;
Lucas Dupin9e484aa2019-06-24 13:38:00 -0700100import com.android.systemui.statusbar.phone.KeyguardBypassController;
Kevin Chyn1123ba72018-10-26 10:34:06 -0700101
Kevin Chyn36778ff2017-09-07 19:55:38 -0700102import com.google.android.collect.Lists;
103
Jason Monkab525272015-07-13 17:02:49 -0400104import java.io.FileDescriptor;
105import java.io.PrintWriter;
Jim Millerdcb3d842012-08-23 19:18:12 -0700106import java.lang.ref.WeakReference;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800107import java.util.ArrayList;
Jim Miller52a61332014-11-12 19:29:51 -0800108import java.util.HashMap;
109import java.util.List;
110import java.util.Map.Entry;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500111import java.util.TimeZone;
Lucas Dupin3d053532019-01-29 12:35:22 -0800112import java.util.function.Consumer;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800113
114/**
115 * Watches for updates that may be interesting to the keyguard, and provides
116 * the up to date information as well as a registration for callbacks that care
117 * to be updated.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800118 */
Adrian Roos46842d92014-03-27 14:58:03 +0100119public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800120
Jim Millerbbf1a742012-07-17 18:30:30 -0700121 private static final String TAG = "KeyguardUpdateMonitor";
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100122 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller52a61332014-11-12 19:29:51 -0800123 private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700124 private static final boolean DEBUG_FACE = true;
Jim Millerbbf1a742012-07-17 18:30:30 -0700125 private static final int LOW_BATTERY_THRESHOLD = 20;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800126
Jorim Jaggie7b12522014-08-06 16:41:21 +0200127 private static final String ACTION_FACE_UNLOCK_STARTED
128 = "com.android.facelock.FACE_UNLOCK_STARTED";
129 private static final String ACTION_FACE_UNLOCK_STOPPED
130 = "com.android.facelock.FACE_UNLOCK_STOPPED";
131
Jim Millerbbf1a742012-07-17 18:30:30 -0700132 // Callback messages
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800133 private static final int MSG_TIME_UPDATE = 301;
134 private static final int MSG_BATTERY_UPDATE = 302;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800135 private static final int MSG_SIM_STATE_CHANGE = 304;
Jim Miller47088bb2009-11-24 00:40:16 -0800136 private static final int MSG_RINGER_MODE_CHANGED = 305;
Jim Millerc23024d2010-02-24 15:37:00 -0800137 private static final int MSG_PHONE_STATE_CHANGED = 306;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700138 private static final int MSG_DEVICE_PROVISIONED = 308;
Jim Miller57375342012-09-09 15:20:31 -0700139 private static final int MSG_DPM_STATE_CHANGED = 309;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500140 private static final int MSG_USER_SWITCHING = 310;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700141 private static final int MSG_KEYGUARD_RESET = 312;
Jim Millerf41fc962014-06-18 16:33:51 -0700142 private static final int MSG_BOOT_COMPLETED = 313;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500143 private static final int MSG_USER_SWITCH_COMPLETE = 314;
Jim Millerf41fc962014-06-18 16:33:51 -0700144 private static final int MSG_USER_INFO_CHANGED = 317;
145 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700146 private static final int MSG_STARTED_WAKING_UP = 319;
147 private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700148 private static final int MSG_STARTED_GOING_TO_SLEEP = 321;
Adrian Roosb6011622014-05-14 15:52:53 +0200149 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700150 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
151 private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
Jason Monk052082c2015-06-11 11:35:23 -0400152 private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
Etan Cohen47051d82015-07-06 16:19:04 -0700153 private static final int MSG_SERVICE_STATE_CHANGE = 330;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700154 private static final int MSG_SCREEN_TURNED_ON = 331;
155 private static final int MSG_SCREEN_TURNED_OFF = 332;
Selim Cinek99415392016-09-09 14:58:41 -0700156 private static final int MSG_DREAMING_STATE_CHANGED = 333;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700157 private static final int MSG_USER_UNLOCKED = 334;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700158 private static final int MSG_ASSISTANT_STACK_CHANGED = 335;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200159 private static final int MSG_BIOMETRIC_AUTHENTICATION_CONTINUE = 336;
Alex Chauff7653d2018-02-01 17:18:08 +0000160 private static final int MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED = 337;
Bill Linef81cbd2018-07-05 17:48:49 +0800161 private static final int MSG_TELEPHONY_CAPABLE = 338;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500162 private static final int MSG_TIMEZONE_UPDATE = 339;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800163
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200164 /** Biometric authentication state: Not listening. */
165 private static final int BIOMETRIC_STATE_STOPPED = 0;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700166
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200167 /** Biometric authentication state: Listening. */
168 private static final int BIOMETRIC_STATE_RUNNING = 1;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700169
170 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200171 * Biometric authentication: Cancelling and waiting for the relevant biometric service to
Jorim Jaggi86bed402015-08-20 18:20:02 -0700172 * send us the confirmation that cancellation has happened.
173 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200174 private static final int BIOMETRIC_STATE_CANCELLING = 2;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700175
176 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200177 * Biometric state: During cancelling we got another request to start listening, so when we
Jorim Jaggi86bed402015-08-20 18:20:02 -0700178 * receive the cancellation done signal, we should start listening again.
179 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200180 private static final int BIOMETRIC_STATE_CANCELLING_RESTARTING = 3;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700181
Lucas Dupin51996bb2019-05-16 17:56:43 -0700182 private static final int BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED = -1;
183 public static final int BIOMETRIC_HELP_FACE_NOT_RECOGNIZED = -2;
184
Adrian Roos0c859ae2015-11-23 16:47:50 -0800185 private static final int DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT = 5000000;
186
Jorim Jaggi031f7952016-09-01 16:39:26 -0700187 private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName(
188 "com.android.settings", "com.android.settings.FallbackHome");
189
Adrian Roosca8a2162017-08-17 19:00:58 +0200190
191 /**
192 * If true, the system is in the half-boot-to-decryption-screen state.
193 * Prudently disable lockscreen.
194 */
195 public static final boolean CORE_APPS_ONLY;
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700196
Adrian Roosca8a2162017-08-17 19:00:58 +0200197 static {
198 try {
199 CORE_APPS_ONLY = IPackageManager.Stub.asInterface(
200 ServiceManager.getService("package")).isOnlyCoreApps();
201 } catch (RemoteException e) {
202 throw e.rethrowFromSystemServer();
203 }
204 }
205
Jim Millerdcb3d842012-08-23 19:18:12 -0700206 private static KeyguardUpdateMonitor sInstance;
207
Jim Millerbbf1a742012-07-17 18:30:30 -0700208 private final Context mContext;
Kevin Chynfdfd2d32019-03-01 14:52:15 -0800209 private final boolean mIsPrimaryUser;
Jim Miller52a61332014-11-12 19:29:51 -0800210 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
Etan Cohen47051d82015-07-06 16:19:04 -0700211 HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700212
Jim Millerbbf1a742012-07-17 18:30:30 -0700213 private int mRingMode;
214 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400215 private boolean mKeyguardIsVisible;
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700216 private boolean mKeyguardGoingAway;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700217 private boolean mGoingToSleep;
Adrian Roosb6011622014-05-14 15:52:53 +0200218 private boolean mBouncer;
Lucas Dupine0516d52019-02-05 17:54:06 -0500219 private boolean mAuthInterruptActive;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800220 private boolean mBootCompleted;
Jorim Jaggi031f7952016-09-01 16:39:26 -0700221 private boolean mNeedsSlowUnlockTransition;
Jorim Jaggid11d1a92016-08-16 16:02:32 -0700222 private boolean mHasLockscreenWallpaper;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700223 private boolean mAssistantVisible;
224 private boolean mKeyguardOccluded;
Kevin Chyn6951d3d2019-06-10 14:07:13 -0700225 private boolean mSecureCameraLaunched;
Bill Linef81cbd2018-07-05 17:48:49 +0800226 @VisibleForTesting
227 protected boolean mTelephonyCapable;
Jim Millerbbf1a742012-07-17 18:30:30 -0700228
Jim Millerdcb3d842012-08-23 19:18:12 -0700229 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700230 private boolean mDeviceProvisioned;
231
Jim Millerdcb3d842012-08-23 19:18:12 -0700232 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700233 private BatteryStatus mBatteryStatus;
234
Lucas Dupin3d053532019-01-29 12:35:22 -0800235 @VisibleForTesting
236 protected StrongAuthTracker mStrongAuthTracker;
Jim Millerbbf1a742012-07-17 18:30:30 -0700237
Jim Miller6212cc02012-09-05 17:35:31 -0700238 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700239 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800240 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700241
Brian Colonnaa5239892013-04-15 11:45:40 -0400242 private boolean mSwitchingUser;
243
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700244 private boolean mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -0700245 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800246 private SubscriptionManager mSubscriptionManager;
247 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700248 private TrustManager mTrustManager;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700249 private UserManager mUserManager;
Lucas Dupin9e484aa2019-06-24 13:38:00 -0700250 private KeyguardBypassController mKeyguardBypassController;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200251 private int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
252 private int mFaceRunningState = BIOMETRIC_STATE_STOPPED;
Michal Karpinskic52f8672016-11-18 11:32:45 +0000253 private LockPatternUtils mLockPatternUtils;
Kevin Chyn36778ff2017-09-07 19:55:38 -0700254 private final IDreamManager mDreamManager;
255 private boolean mIsDreaming;
Alex Chauff7653d2018-02-01 17:18:08 +0000256 private final DevicePolicyManager mDevicePolicyManager;
257 private boolean mLogoutEnabled;
Lucas Dupinca88e5f2019-05-14 16:11:08 -0700258 // If the user long pressed the lock icon, disabling face auth for the current session.
259 private boolean mLockIconPressed;
Jim Miller20daffd2013-10-07 14:59:53 -0700260
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700261 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200262 * Short delay before restarting biometric authentication after a successful try
263 * This should be slightly longer than the time between on<biometric>Authenticated
264 * (e.g. onFingerprintAuthenticated) and setKeyguardGoingAway(true).
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700265 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200266 private static final int BIOMETRIC_CONTINUE_DELAY_MS = 500;
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700267
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700268 // If the HAL dies or is unable to authenticate, keyguard should retry after a short delay
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200269 private int mHardwareFingerprintUnavailableRetryCount = 0;
270 private int mHardwareFaceUnavailableRetryCount = 0;
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700271 private static final int HAL_ERROR_RETRY_TIMEOUT = 500; // ms
272 private static final int HAL_ERROR_RETRY_MAX = 10;
Kevin Chyn0c45b072017-04-24 16:27:11 -0700273
Jason Monk7bb59302018-05-10 19:38:18 -0700274 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700275 @Override
276 public void handleMessage(Message msg) {
277 switch (msg.what) {
278 case MSG_TIME_UPDATE:
279 handleTimeUpdate();
280 break;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500281 case MSG_TIMEZONE_UPDATE:
282 handleTimeZoneUpdate((String) msg.obj);
283 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700284 case MSG_BATTERY_UPDATE:
285 handleBatteryUpdate((BatteryStatus) msg.obj);
286 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700287 case MSG_SIM_STATE_CHANGE:
Jim Miller52a61332014-11-12 19:29:51 -0800288 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700289 break;
290 case MSG_RINGER_MODE_CHANGED:
291 handleRingerModeChange(msg.arg1);
292 break;
293 case MSG_PHONE_STATE_CHANGED:
Adrian Roosb6011622014-05-14 15:52:53 +0200294 handlePhoneStateChanged((String) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700295 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700296 case MSG_DEVICE_PROVISIONED:
297 handleDeviceProvisioned();
298 break;
299 case MSG_DPM_STATE_CHANGED:
300 handleDevicePolicyManagerStateChanged();
301 break;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500302 case MSG_USER_SWITCHING:
Adrian Roosb6011622014-05-14 15:52:53 +0200303 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
Chris Wrenf41c61b2012-11-29 15:19:54 -0500304 break;
305 case MSG_USER_SWITCH_COMPLETE:
306 handleUserSwitchComplete(msg.arg1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700307 break;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700308 case MSG_KEYGUARD_RESET:
309 handleKeyguardReset();
310 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200311 case MSG_KEYGUARD_BOUNCER_CHANGED:
312 handleKeyguardBouncerChanged(msg.arg1);
313 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800314 case MSG_BOOT_COMPLETED:
315 handleBootCompleted();
316 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700317 case MSG_USER_INFO_CHANGED:
318 handleUserInfoChanged(msg.arg1);
319 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400320 case MSG_REPORT_EMERGENCY_CALL_ACTION:
321 handleReportEmergencyCallAction();
322 break;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700323 case MSG_STARTED_GOING_TO_SLEEP:
324 handleStartedGoingToSleep(msg.arg1);
325 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700326 case MSG_FINISHED_GOING_TO_SLEEP:
327 handleFinishedGoingToSleep(msg.arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700328 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700329 case MSG_STARTED_WAKING_UP:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700330 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_STARTED_WAKING_UP");
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700331 handleStartedWakingUp();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700332 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -0700333 break;
Jorim Jaggie7b12522014-08-06 16:41:21 +0200334 case MSG_FACE_UNLOCK_STATE_CHANGED:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700335 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_FACE_UNLOCK_STATE_CHANGED");
Adrian Roos4a410172014-08-20 17:41:44 +0200336 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
Nick Desaulniers1d396752016-07-25 15:05:33 -0700337 Trace.endSection();
Jorim Jaggie7b12522014-08-06 16:41:21 +0200338 break;
Jim Miller52a61332014-11-12 19:29:51 -0800339 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
340 handleSimSubscriptionInfoChanged();
341 break;
Jason Monk052082c2015-06-11 11:35:23 -0400342 case MSG_AIRPLANE_MODE_CHANGED:
343 handleAirplaneModeChanged();
344 break;
Etan Cohen47051d82015-07-06 16:19:04 -0700345 case MSG_SERVICE_STATE_CHANGE:
Bonian Chena7e9e8c2019-06-02 23:59:31 +0000346 handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
Etan Cohen47051d82015-07-06 16:19:04 -0700347 break;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700348 case MSG_SCREEN_TURNED_ON:
349 handleScreenTurnedOn();
350 break;
351 case MSG_SCREEN_TURNED_OFF:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700352 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_SCREEN_TURNED_ON");
Jorim Jaggif1518da2015-07-30 11:56:36 -0700353 handleScreenTurnedOff();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700354 Trace.endSection();
Jorim Jaggif1518da2015-07-30 11:56:36 -0700355 break;
Selim Cinek99415392016-09-09 14:58:41 -0700356 case MSG_DREAMING_STATE_CHANGED:
357 handleDreamingStateChanged(msg.arg1);
358 break;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700359 case MSG_USER_UNLOCKED:
360 handleUserUnlocked();
361 break;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700362 case MSG_ASSISTANT_STACK_CHANGED:
Lucas Dupin3d053532019-01-29 12:35:22 -0800363 setAssistantVisible((boolean) msg.obj);
Kevin Chyn2fefd462017-04-28 12:18:19 -0700364 break;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200365 case MSG_BIOMETRIC_AUTHENTICATION_CONTINUE:
366 updateBiometricListeningState();
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700367 break;
Alex Chauff7653d2018-02-01 17:18:08 +0000368 case MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED:
369 updateLogoutEnabled();
370 break;
Bill Linef81cbd2018-07-05 17:48:49 +0800371 case MSG_TELEPHONY_CAPABLE:
Lucas Dupin3d053532019-01-29 12:35:22 -0800372 updateTelephonyCapable((boolean) msg.obj);
Bill Linef81cbd2018-07-05 17:48:49 +0800373 break;
Jason Monk7bb59302018-05-10 19:38:18 -0700374 default:
375 super.handleMessage(msg);
376 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700377 }
378 }
379 };
380
Lucas Dupin7d95f152019-07-17 16:25:54 -0700381 private SparseBooleanArray mFaceSettingEnabledForUser = new SparseBooleanArray();
Kevin Chynb7b54a62018-09-28 18:48:12 -0700382 private BiometricManager mBiometricManager;
383 private IBiometricEnabledOnKeyguardCallback mBiometricEnabledCallback =
384 new IBiometricEnabledOnKeyguardCallback.Stub() {
385 @Override
Lucas Dupin7d95f152019-07-17 16:25:54 -0700386 public void onChanged(BiometricSourceType type, boolean enabled, int userId)
387 throws RemoteException {
Kevin Chynb7b54a62018-09-28 18:48:12 -0700388 if (type == BiometricSourceType.FACE) {
Lucas Dupin7d95f152019-07-17 16:25:54 -0700389 mFaceSettingEnabledForUser.put(userId, enabled);
Kevin Chyn1e043d472019-03-11 14:48:17 -0700390 updateFaceListeningState();
Kevin Chynb7b54a62018-09-28 18:48:12 -0700391 }
392 }
393 };
394
Fabian Kozynskiccde55d2019-06-26 10:06:09 -0400395 private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
396 @Override
397 public void onActiveDataSubscriptionIdChanged(int subId) {
398 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
399 }
400 };
401
Wink Savilled09c4ca2014-11-22 10:08:16 -0800402 private OnSubscriptionsChangedListener mSubscriptionListener =
403 new OnSubscriptionsChangedListener() {
Jim Miller52a61332014-11-12 19:29:51 -0800404 @Override
Wink Savilled09c4ca2014-11-22 10:08:16 -0800405 public void onSubscriptionsChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800406 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
407 }
408 };
409
Adrian Roos46842d92014-03-27 14:58:03 +0100410 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200411 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Jim Miller9f0753f2015-03-23 23:59:22 -0700412 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200413 private SparseBooleanArray mUserFaceAuthenticated = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200414 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100415
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700416 private static int sCurrentUser;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200417 private Runnable mUpdateBiometricListeningState = this::updateBiometricListeningState;
Adrian Roos30a2ae62018-04-25 19:09:50 +0200418 private static boolean sDisableHandlerCheckForTesting;
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700419
420 public synchronized static void setCurrentUser(int currentUser) {
421 sCurrentUser = currentUser;
422 }
423
424 public synchronized static int getCurrentUser() {
425 return sCurrentUser;
426 }
427
Adrian Roos46842d92014-03-27 14:58:03 +0100428 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700429 public void onTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200430 checkIsHandlerThread();
Adrian Roos46842d92014-03-27 14:58:03 +0100431 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200432 for (int i = 0; i < mCallbacks.size(); i++) {
433 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
434 if (cb != null) {
435 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700436 if (enabled && flags != 0) {
437 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200438 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200439 }
440 }
Adrian Roos46842d92014-03-27 14:58:03 +0100441 }
442
Lucas Dupinef886542018-01-03 16:03:07 -0800443 @Override
444 public void onTrustError(CharSequence message) {
445 dispatchErrorMessage(message);
446 }
447
Adrian Roos30a2ae62018-04-25 19:09:50 +0200448 private void handleSimSubscriptionInfoChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800449 if (DEBUG_SIM_STATES) {
450 Log.v(TAG, "onSubscriptionInfoChanged()");
Fabian Kozynskiccde55d2019-06-26 10:06:09 -0400451 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList(false);
Wink Savilled09c4ca2014-11-22 10:08:16 -0800452 if (sil != null) {
453 for (SubscriptionInfo subInfo : sil) {
454 Log.v(TAG, "SubInfo:" + subInfo);
455 }
456 } else {
457 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800458 }
459 }
460 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
461
462 // Hack level over 9000: Because the subscription id is not yet valid when we see the
463 // first update in handleSimStateChange, we need to force refresh all all SIM states
464 // so the subscription id for them is consistent.
Richard Choue0381b82018-04-24 03:48:59 +0000465 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
466 for (int i = 0; i < subscriptionInfos.size(); i++) {
467 SubscriptionInfo info = subscriptionInfos.get(i);
468 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
469 if (changed) {
470 changedSubscriptions.add(info);
471 }
472 }
473 for (int i = 0; i < changedSubscriptions.size(); i++) {
474 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800475 for (int j = 0; j < mCallbacks.size(); j++) {
476 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
477 if (cb != null) {
478 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
479 }
480 }
481 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500482 for (int j = 0; j < mCallbacks.size(); j++) {
483 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
484 if (cb != null) {
485 cb.onRefreshCarrierInfo();
486 }
487 }
Jim Miller52a61332014-11-12 19:29:51 -0800488 }
489
Jason Monk052082c2015-06-11 11:35:23 -0400490 private void handleAirplaneModeChanged() {
491 for (int j = 0; j < mCallbacks.size(); j++) {
492 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
493 if (cb != null) {
494 cb.onRefreshCarrierInfo();
495 }
496 }
497 }
498
Wink Savilled09c4ca2014-11-22 10:08:16 -0800499 /** @return List of SubscriptionInfo records, maybe empty but never null */
Adrian Roos316bf542016-08-23 17:53:07 +0200500 public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800501 List<SubscriptionInfo> sil = mSubscriptionInfo;
502 if (sil == null || forceReload) {
Fabian Kozynskiccde55d2019-06-26 10:06:09 -0400503 sil = mSubscriptionManager.getActiveSubscriptionInfoList(false);
Wink Savilled09c4ca2014-11-22 10:08:16 -0800504 }
505 if (sil == null) {
506 // getActiveSubscriptionInfoList was null callers expect an empty list.
507 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
508 } else {
509 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800510 }
511 return mSubscriptionInfo;
512 }
513
Adrian Roos7861c662014-07-25 15:37:28 +0200514 @Override
515 public void onTrustManagedChanged(boolean managed, int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200516 checkIsHandlerThread();
Adrian Roos7861c662014-07-25 15:37:28 +0200517 mUserTrustIsManaged.put(userId, managed);
518
519 for (int i = 0; i < mCallbacks.size(); i++) {
520 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
521 if (cb != null) {
522 cb.onTrustManagedChanged(userId);
523 }
524 }
525 }
526
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700527 /**
528 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is goingAway
529 * @param goingAway
530 */
531 public void setKeyguardGoingAway(boolean goingAway) {
532 mKeyguardGoingAway = goingAway;
Kevin Chyne22f1342017-09-26 10:03:38 -0700533 updateFingerprintListeningState();
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700534 }
535
Kevin Chyn2fefd462017-04-28 12:18:19 -0700536 /**
537 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is occluded
538 * @param occluded
539 */
540 public void setKeyguardOccluded(boolean occluded) {
541 mKeyguardOccluded = occluded;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200542 updateBiometricListeningState();
Kevin Chyn2fefd462017-04-28 12:18:19 -0700543 }
544
Kevin Chyn36778ff2017-09-07 19:55:38 -0700545 /**
Kevin Chyn6951d3d2019-06-10 14:07:13 -0700546 * Invoked when the secure camera is launched.
547 */
548 public void onCameraLaunched() {
549 mSecureCameraLaunched = true;
550 updateBiometricListeningState();
551 }
552
553 /**
Kevin Chyn36778ff2017-09-07 19:55:38 -0700554 * @return a cached version of DreamManager.isDreaming()
555 */
556 public boolean isDreaming() {
557 return mIsDreaming;
558 }
559
560 /**
561 * If the device is dreaming, awakens the device
562 */
563 public void awakenFromDream() {
564 if (mIsDreaming && mDreamManager != null) {
565 try {
566 mDreamManager.awaken();
567 } catch (RemoteException e) {
568 Log.e(TAG, "Unable to awaken from dream");
569 }
570 }
571 }
572
Lucas Dupin3d053532019-01-29 12:35:22 -0800573 @VisibleForTesting
574 protected void onFingerprintAuthenticated(int userId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700575 Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
Jim Miller9f0753f2015-03-23 23:59:22 -0700576 mUserFingerprintAuthenticated.put(userId, true);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700577 // Update/refresh trust state only if user can skip bouncer
578 if (getUserCanSkipBouncer(userId)) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200579 mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FINGERPRINT);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700580 }
Kevin Chyn625a0142017-04-10 14:53:59 -0700581 // Don't send cancel if authentication succeeds
582 mFingerprintCancelSignal = null;
Jim Millerf41fc962014-06-18 16:33:51 -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.onBiometricAuthenticated(userId, BiometricSourceType.FINGERPRINT);
Jim Millerf41fc962014-06-18 16:33:51 -0700587 }
588 }
Kevin Chyn2fefd462017-04-28 12:18:19 -0700589
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200590 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE),
591 BIOMETRIC_CONTINUE_DELAY_MS);
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700592
Kevin Chyn2fefd462017-04-28 12:18:19 -0700593 // Only authenticate fingerprint once when assistant is visible
594 mAssistantVisible = false;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700595
Nick Desaulniers1d396752016-07-25 15:05:33 -0700596 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700597 }
598
Jim Millerce7eb6d2015-04-03 19:29:13 -0700599 private void handleFingerprintAuthFailed() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700600 for (int i = 0; i < mCallbacks.size(); i++) {
601 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
602 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200603 cb.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700604 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700605 }
Lucas Dupin51996bb2019-05-16 17:56:43 -0700606 handleFingerprintHelp(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
607 mContext.getString(R.string.kg_fingerprint_not_recognized));
Jim Millerce7eb6d2015-04-03 19:29:13 -0700608 }
Jim Millerf41fc962014-06-18 16:33:51 -0700609
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700610 private void handleFingerprintAcquired(int acquireInfo) {
611 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
612 return;
613 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700614 for (int i = 0; i < mCallbacks.size(); i++) {
615 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
616 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200617 cb.onBiometricAcquired(BiometricSourceType.FINGERPRINT);
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700618 }
619 }
620 }
621
Jim Miller837fa7e2016-08-08 20:16:22 -0700622 private void handleFingerprintAuthenticated(int authUserId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700623 Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
Jim Millerf41fc962014-06-18 16:33:51 -0700624 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700625 final int userId;
626 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800627 userId = ActivityManager.getService().getCurrentUser().id;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700628 } catch (RemoteException e) {
629 Log.e(TAG, "Failed to get current user id: ", e);
630 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700631 }
Jim Miller837fa7e2016-08-08 20:16:22 -0700632 if (userId != authUserId) {
633 Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId);
634 return;
635 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700636 if (isFingerprintDisabled(userId)) {
637 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
638 return;
639 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700640 onFingerprintAuthenticated(userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700641 } finally {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200642 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Jim Millerf41fc962014-06-18 16:33:51 -0700643 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700644 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700645 }
646
Jim Miller9f0753f2015-03-23 23:59:22 -0700647 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700648 for (int i = 0; i < mCallbacks.size(); i++) {
649 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
650 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200651 cb.onBiometricHelp(msgId, helpString, BiometricSourceType.FINGERPRINT);
Jim Miller9f0753f2015-03-23 23:59:22 -0700652 }
653 }
654 }
655
Kevin Chyn0c45b072017-04-24 16:27:11 -0700656 private Runnable mRetryFingerprintAuthentication = new Runnable() {
657 @Override
658 public void run() {
659 Log.w(TAG, "Retrying fingerprint after HW unavailable, attempt " +
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200660 mHardwareFingerprintUnavailableRetryCount);
Kevin Chyn0c45b072017-04-24 16:27:11 -0700661 updateFingerprintListeningState();
662 }
663 };
664
Jim Miller9f0753f2015-03-23 23:59:22 -0700665 private void handleFingerprintError(int msgId, String errString) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700666 if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200667 && mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
668 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Kevin Chyn1123ba72018-10-26 10:34:06 -0700669 updateFingerprintListeningState();
Jorim Jaggi86bed402015-08-20 18:20:02 -0700670 } else {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200671 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Jorim Jaggi86bed402015-08-20 18:20:02 -0700672 }
Kevin Chyn0c45b072017-04-24 16:27:11 -0700673
674 if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) {
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700675 if (mHardwareFingerprintUnavailableRetryCount < HAL_ERROR_RETRY_MAX) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200676 mHardwareFingerprintUnavailableRetryCount++;
Kevin Chyn0c45b072017-04-24 16:27:11 -0700677 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700678 mHandler.postDelayed(mRetryFingerprintAuthentication, HAL_ERROR_RETRY_TIMEOUT);
Kevin Chyn0c45b072017-04-24 16:27:11 -0700679 }
680 }
681
Kevin Chyndf9d33e2017-05-03 21:40:12 -0700682 if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
Lucas Dupin8eec2682019-07-01 16:41:17 -0700683 mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
Kevin Chyndf9d33e2017-05-03 21:40:12 -0700684 getCurrentUser());
685 }
686
Jim Miller9f0753f2015-03-23 23:59:22 -0700687 for (int i = 0; i < mCallbacks.size(); i++) {
688 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
689 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200690 cb.onBiometricError(msgId, errString, BiometricSourceType.FINGERPRINT);
Jim Millerf41fc962014-06-18 16:33:51 -0700691 }
692 }
693 }
694
Jorim Jaggi3a464782015-08-28 16:59:13 -0700695 private void handleFingerprintLockoutReset() {
696 updateFingerprintListeningState();
697 }
698
Jorim Jaggi86bed402015-08-20 18:20:02 -0700699 private void setFingerprintRunningState(int fingerprintRunningState) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200700 boolean wasRunning = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
701 boolean isRunning = fingerprintRunningState == BIOMETRIC_STATE_RUNNING;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700702 mFingerprintRunningState = fingerprintRunningState;
Kevin Chynb4514d22019-04-15 13:47:25 -0700703 Log.d(TAG, "fingerprintRunningState: " + mFingerprintRunningState);
Jorim Jaggi86bed402015-08-20 18:20:02 -0700704 // Clients of KeyguardUpdateMonitor don't care about the internal state about the
Kevin Chynb4514d22019-04-15 13:47:25 -0700705 // asynchronousness of the cancel cycle. So only notify them if the actually running state
Jorim Jaggi86bed402015-08-20 18:20:02 -0700706 // has changed.
707 if (wasRunning != isRunning) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700708 notifyFingerprintRunningStateChanged();
709 }
710 }
711
712 private void notifyFingerprintRunningStateChanged() {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200713 checkIsHandlerThread();
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700714 for (int i = 0; i < mCallbacks.size(); i++) {
715 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
716 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200717 cb.onBiometricRunningStateChanged(isFingerprintDetectionRunning(),
718 BiometricSourceType.FINGERPRINT);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700719 }
720 }
721 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200722
Lucas Dupin3d053532019-01-29 12:35:22 -0800723 @VisibleForTesting
724 protected void onFaceAuthenticated(int userId) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200725 Trace.beginSection("KeyGuardUpdateMonitor#onFaceAuthenticated");
726 mUserFaceAuthenticated.put(userId, true);
727 // Update/refresh trust state only if user can skip bouncer
728 if (getUserCanSkipBouncer(userId)) {
729 mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FACE);
730 }
731 // Don't send cancel if authentication succeeds
732 mFaceCancelSignal = null;
733 for (int i = 0; i < mCallbacks.size(); i++) {
734 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
735 if (cb != null) {
736 cb.onBiometricAuthenticated(userId,
737 BiometricSourceType.FACE);
738 }
739 }
740
741 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE),
742 BIOMETRIC_CONTINUE_DELAY_MS);
743
744 // Only authenticate face once when assistant is visible
745 mAssistantVisible = false;
746
747 Trace.endSection();
748 }
749
750 private void handleFaceAuthFailed() {
Lucas Dupin38314812019-02-15 14:10:55 -0800751 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200752 for (int i = 0; i < mCallbacks.size(); i++) {
753 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
754 if (cb != null) {
755 cb.onBiometricAuthFailed(BiometricSourceType.FACE);
756 }
757 }
Lucas Dupin51996bb2019-05-16 17:56:43 -0700758 handleFaceHelp(BIOMETRIC_HELP_FACE_NOT_RECOGNIZED,
759 mContext.getString(R.string.kg_face_not_recognized));
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200760 }
761
762 private void handleFaceAcquired(int acquireInfo) {
763 if (acquireInfo != FaceManager.FACE_ACQUIRED_GOOD) {
764 return;
765 }
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700766 if (DEBUG_FACE) Log.d(TAG, "Face acquired");
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200767 for (int i = 0; i < mCallbacks.size(); i++) {
768 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
769 if (cb != null) {
770 cb.onBiometricAcquired(BiometricSourceType.FACE);
771 }
772 }
773 }
774
775 private void handleFaceAuthenticated(int authUserId) {
776 Trace.beginSection("KeyGuardUpdateMonitor#handlerFaceAuthenticated");
777 try {
Lucas Dupin9bae9c22019-06-04 16:37:40 -0700778 if (mGoingToSleep) {
779 Log.d(TAG, "Aborted successful auth because device is going to sleep.");
780 return;
781 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200782 final int userId;
783 try {
784 userId = ActivityManager.getService().getCurrentUser().id;
785 } catch (RemoteException e) {
786 Log.e(TAG, "Failed to get current user id: ", e);
787 return;
788 }
789 if (userId != authUserId) {
790 Log.d(TAG, "Face authenticated for wrong user: " + authUserId);
791 return;
792 }
793 if (isFaceDisabled(userId)) {
794 Log.d(TAG, "Face authentication disabled by DPM for userId: " + userId);
795 return;
796 }
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700797 if (DEBUG_FACE) Log.d(TAG, "Face auth succeeded for user " + userId);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200798 onFaceAuthenticated(userId);
799 } finally {
800 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
801 }
802 Trace.endSection();
803 }
804
805 private void handleFaceHelp(int msgId, String helpString) {
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700806 if (DEBUG_FACE) Log.d(TAG, "Face help received: " + helpString);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200807 for (int i = 0; i < mCallbacks.size(); i++) {
808 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
809 if (cb != null) {
810 cb.onBiometricHelp(msgId, helpString, BiometricSourceType.FACE);
811 }
812 }
813 }
814
815 private Runnable mRetryFaceAuthentication = new Runnable() {
816 @Override
817 public void run() {
818 Log.w(TAG, "Retrying face after HW unavailable, attempt " +
819 mHardwareFaceUnavailableRetryCount);
820 updateFaceListeningState();
821 }
822 };
823
824 private void handleFaceError(int msgId, String errString) {
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700825 if (DEBUG_FACE) Log.d(TAG, "Face error received: " + errString);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200826 if (msgId == FaceManager.FACE_ERROR_CANCELED
827 && mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
828 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
Kevin Chyn1123ba72018-10-26 10:34:06 -0700829 updateFaceListeningState();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200830 } else {
831 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
832 }
833
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700834 if (msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE
835 || msgId == FaceManager.FACE_ERROR_UNABLE_TO_PROCESS) {
836 if (mHardwareFaceUnavailableRetryCount < HAL_ERROR_RETRY_MAX) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200837 mHardwareFaceUnavailableRetryCount++;
838 mHandler.removeCallbacks(mRetryFaceAuthentication);
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700839 mHandler.postDelayed(mRetryFaceAuthentication, HAL_ERROR_RETRY_TIMEOUT);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200840 }
841 }
842
843 if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
Lucas Dupin8eec2682019-07-01 16:41:17 -0700844 mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200845 getCurrentUser());
846 }
847
848 for (int i = 0; i < mCallbacks.size(); i++) {
849 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
850 if (cb != null) {
851 cb.onBiometricError(msgId, errString,
852 BiometricSourceType.FACE);
853 }
854 }
855 }
856
857 private void handleFaceLockoutReset() {
858 updateFaceListeningState();
859 }
860
861 private void setFaceRunningState(int faceRunningState) {
862 boolean wasRunning = mFaceRunningState == BIOMETRIC_STATE_RUNNING;
863 boolean isRunning = faceRunningState == BIOMETRIC_STATE_RUNNING;
864 mFaceRunningState = faceRunningState;
Kevin Chynb4514d22019-04-15 13:47:25 -0700865 Log.d(TAG, "faceRunningState: " + mFaceRunningState);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200866 // Clients of KeyguardUpdateMonitor don't care about the internal state or about the
Kevin Chynb4514d22019-04-15 13:47:25 -0700867 // asynchronousness of the cancel cycle. So only notify them if the actually running state
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200868 // has changed.
869 if (wasRunning != isRunning) {
870 notifyFaceRunningStateChanged();
871 }
872 }
873
874 private void notifyFaceRunningStateChanged() {
875 for (int i = 0; i < mCallbacks.size(); i++) {
876 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
877 if (cb != null) {
878 cb.onBiometricRunningStateChanged(isFaceDetectionRunning(),
879 BiometricSourceType.FACE);
880 }
881 }
882 }
883
Adrian Roos4a410172014-08-20 17:41:44 +0200884 private void handleFaceUnlockStateChanged(boolean running, int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200885 checkIsHandlerThread();
Adrian Roos4a410172014-08-20 17:41:44 +0200886 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200887 for (int i = 0; i < mCallbacks.size(); i++) {
888 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
889 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200890 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200891 }
892 }
893 }
894
Adrian Roos4a410172014-08-20 17:41:44 +0200895 public boolean isFaceUnlockRunning(int userId) {
896 return mUserFaceUnlockRunning.get(userId);
897 }
898
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700899 public boolean isFingerprintDetectionRunning() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200900 return mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
901 }
902
903 public boolean isFaceDetectionRunning() {
904 return mFaceRunningState == BIOMETRIC_STATE_RUNNING;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700905 }
906
Jim Miller50e62182014-04-23 17:25:00 -0700907 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100908 // Don't allow trust agent if device is secured with a SIM PIN. This is here
909 // mainly because there's no other way to prompt the user to enter their SIM PIN
910 // once they get past the keyguard screen.
911 final boolean disabledBySimPin = isSimPinSecure();
912 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700913 }
914
Jim Miller06e34502014-07-17 14:46:05 -0700915 private boolean isFingerprintDisabled(int userId) {
916 final DevicePolicyManager dpm =
917 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
918 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
Adrian Roos733b6632015-08-21 14:32:35 -0700919 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0
920 || isSimPinSecure();
Jim Miller06e34502014-07-17 14:46:05 -0700921 }
922
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200923 private boolean isFaceDisabled(int userId) {
924 final DevicePolicyManager dpm =
925 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
926 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
927 & DevicePolicyManager.KEYGUARD_DISABLE_FACE) != 0
928 || isSimPinSecure();
929 }
930
931
Selim Cineke8bae622015-07-15 13:24:06 -0700932 public boolean getUserCanSkipBouncer(int userId) {
Steven Wucfe398d2019-03-21 11:32:15 -0400933 return getUserHasTrust(userId) || getUserUnlockedWithBiometric(userId);
Selim Cineke8bae622015-07-15 13:24:06 -0700934 }
935
Adrian Roos46842d92014-03-27 14:58:03 +0100936 public boolean getUserHasTrust(int userId) {
Selim Cineke8bae622015-07-15 13:24:06 -0700937 return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100938 }
939
Steven Wucfe398d2019-03-21 11:32:15 -0400940 /**
941 * Returns whether the user is unlocked with biometrics.
942 */
943 public boolean getUserUnlockedWithBiometric(int userId) {
944 boolean fingerprintOrFace = mUserFingerprintAuthenticated.get(userId)
945 || mUserFaceAuthenticated.get(userId);
946 return fingerprintOrFace && isUnlockingWithBiometricAllowed();
947 }
948
Adrian Roos7861c662014-07-25 15:37:28 +0200949 public boolean getUserTrustIsManaged(int userId) {
950 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
951 }
952
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200953 public boolean isUnlockingWithBiometricAllowed() {
954 return mStrongAuthTracker.isUnlockingWithBiometricAllowed();
Adrian Roosb5e47222015-08-14 15:53:06 -0700955 }
956
Lucas Dupin16013822018-05-17 18:00:16 -0700957 public boolean isUserInLockdown(int userId) {
Lucas Dupin8eec2682019-07-01 16:41:17 -0700958 return containsFlag(mStrongAuthTracker.getStrongAuthForUser(userId),
959 STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
Lucas Dupin16013822018-05-17 18:00:16 -0700960 }
961
Lucas Dupin7825b942019-06-03 20:22:39 -0700962 public boolean userNeedsStrongAuth() {
963 return mStrongAuthTracker.getStrongAuthForUser(getCurrentUser())
964 != LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
965 }
966
Lucas Dupin8eec2682019-07-01 16:41:17 -0700967 private boolean containsFlag(int haystack, int needle) {
968 return (haystack & needle) != 0;
969 }
970
Jorim Jaggi031f7952016-09-01 16:39:26 -0700971 public boolean needsSlowUnlockTransition() {
972 return mNeedsSlowUnlockTransition;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700973 }
974
Adrian Roosb5e47222015-08-14 15:53:06 -0700975 public StrongAuthTracker getStrongAuthTracker() {
976 return mStrongAuthTracker;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700977 }
978
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700979 private void notifyStrongAuthStateChanged(int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200980 checkIsHandlerThread();
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700981 for (int i = 0; i < mCallbacks.size(); i++) {
982 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
983 if (cb != null) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700984 cb.onStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700985 }
986 }
Selim Cinek1fcafc42015-07-20 14:39:25 -0700987 }
988
Adrian Roos91ba3072017-02-14 16:50:46 +0100989 public boolean isScreenOn() {
990 return mScreenOn;
991 }
992
Lucas Dupinef886542018-01-03 16:03:07 -0800993 private void dispatchErrorMessage(CharSequence message) {
994 for (int i = 0; i < mCallbacks.size(); i++) {
995 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
996 if (cb != null) {
997 cb.onTrustAgentErrorMessage(message);
998 }
999 }
1000 }
1001
Lucas Dupin3d053532019-01-29 12:35:22 -08001002 @VisibleForTesting
1003 void setAssistantVisible(boolean assistantVisible) {
1004 mAssistantVisible = assistantVisible;
1005 updateBiometricListeningState();
1006 }
1007
Jim Miller8f09fd22013-03-14 19:04:28 -07001008 static class DisplayClientState {
1009 public int clientGeneration;
1010 public boolean clearing;
1011 public PendingIntent intent;
1012 public int playbackState;
1013 public long playbackEventTime;
1014 }
1015
1016 private DisplayClientState mDisplayClientState = new DisplayClientState();
1017
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001018 @VisibleForTesting
Lucas Dupin7ff82b02018-05-16 12:14:10 -07001019 protected final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001020
Jim Millerd72d5ac2015-09-29 18:55:32 -07001021 @Override
Jim Millerbbf1a742012-07-17 18:30:30 -07001022 public void onReceive(Context context, Intent intent) {
1023 final String action = intent.getAction();
1024 if (DEBUG) Log.d(TAG, "received broadcast " + action);
1025
1026 if (Intent.ACTION_TIME_TICK.equals(action)
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05001027 || Intent.ACTION_TIME_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -07001028 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05001029 } else if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
1030 final Message msg = mHandler.obtainMessage(
1031 MSG_TIMEZONE_UPDATE, intent.getStringExtra("time-zone"));
1032 mHandler.sendMessage(msg);
Jim Millerbbf1a742012-07-17 18:30:30 -07001033 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
1034 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
1035 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
1036 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
1037 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
Adrian Roos0c859ae2015-11-23 16:47:50 -08001038
1039 final int maxChargingMicroAmp = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
1040 int maxChargingMicroVolt = intent.getIntExtra(EXTRA_MAX_CHARGING_VOLTAGE, -1);
1041 final int maxChargingMicroWatt;
1042
1043 if (maxChargingMicroVolt <= 0) {
1044 maxChargingMicroVolt = DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT;
1045 }
1046 if (maxChargingMicroAmp > 0) {
1047 // Calculating muW = muA * muV / (10^6 mu^2 / mu); splitting up the divisor
1048 // to maintain precision equally on both factors.
1049 maxChargingMicroWatt = (maxChargingMicroAmp / 1000)
1050 * (maxChargingMicroVolt / 1000);
1051 } else {
1052 maxChargingMicroWatt = -1;
1053 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001054 final Message msg = mHandler.obtainMessage(
Adrian Roos7b043112015-07-10 13:00:33 -07001055 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
Adrian Roos0c859ae2015-11-23 16:47:50 -08001056 maxChargingMicroWatt));
Jim Millerbbf1a742012-07-17 18:30:30 -07001057 mHandler.sendMessage(msg);
1058 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Bill Linef81cbd2018-07-05 17:48:49 +08001059 SimData args = SimData.fromIntent(intent);
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001060 // ACTION_SIM_STATE_CHANGED is rebroadcast after unlocking the device to
1061 // keep compatibility with apps that aren't direct boot aware.
1062 // SysUI should just ignore this broadcast because it was already received
1063 // and processed previously.
1064 if (intent.getBooleanExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
Bill Linef81cbd2018-07-05 17:48:49 +08001065 // Guarantee mTelephonyCapable state after SysUI crash and restart
1066 if (args.simState == State.ABSENT) {
1067 mHandler.obtainMessage(MSG_TELEPHONY_CAPABLE, true).sendToTarget();
1068 }
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001069 return;
1070 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001071 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -08001072 Log.v(TAG, "action " + action
1073 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
1074 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -07001075 }
Jim Miller52a61332014-11-12 19:29:51 -08001076 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
1077 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -07001078 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
1079 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
1080 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
1081 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
1082 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
1083 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Jason Monk052082c2015-06-11 11:35:23 -04001084 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
1085 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001086 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -07001087 dispatchBootCompleted();
Etan Cohen47051d82015-07-06 16:19:04 -07001088 } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
1089 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
1090 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
1091 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
1092 if (DEBUG) {
1093 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
1094 + subId);
1095 }
Bonian Chena7e9e8c2019-06-02 23:59:31 +00001096 mHandler.sendMessage(
1097 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
Fabian Kozynskiccde55d2019-06-26 10:06:09 -04001098 } else if (TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED.equals(action)) {
1099 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
Alex Chauff7653d2018-02-01 17:18:08 +00001100 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
1101 action)) {
1102 mHandler.sendEmptyMessage(MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001103 }
1104 }
1105 };
Jim Miller2de5ee82012-06-14 22:22:50 -07001106
Lucas Dupin3d053532019-01-29 12:35:22 -08001107 @VisibleForTesting
1108 protected final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001109
Jim Millerd72d5ac2015-09-29 18:55:32 -07001110 @Override
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001111 public void onReceive(Context context, Intent intent) {
1112 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +02001113 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
1114 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
1115 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001116 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
1117 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +02001118 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001119 Trace.beginSection("KeyguardUpdateMonitor.mBroadcastAllReceiver#onReceive ACTION_FACE_UNLOCK_STARTED");
Adrian Roos48c796c2014-09-01 14:59:23 +02001120 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
1121 getSendingUserId()));
Nick Desaulniers1d396752016-07-25 15:05:33 -07001122 Trace.endSection();
Adrian Roos48c796c2014-09-01 14:59:23 +02001123 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
1124 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
1125 getSendingUserId()));
1126 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
1127 .equals(action)) {
1128 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001129 } else if (ACTION_USER_UNLOCKED.equals(action)) {
1130 mHandler.sendEmptyMessage(MSG_USER_UNLOCKED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001131 }
1132 }
1133 };
Jim Miller9f0753f2015-03-23 23:59:22 -07001134
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001135 private final FingerprintManager.LockoutResetCallback mFingerprintLockoutResetCallback
Jorim Jaggi3a464782015-08-28 16:59:13 -07001136 = new FingerprintManager.LockoutResetCallback() {
1137 @Override
1138 public void onLockoutReset() {
1139 handleFingerprintLockoutReset();
1140 }
1141 };
1142
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001143 private final FaceManager.LockoutResetCallback mFaceLockoutResetCallback
1144 = new FaceManager.LockoutResetCallback() {
1145 @Override
1146 public void onLockoutReset() {
1147 handleFaceLockoutReset();
1148 }
1149 };
1150
1151 private FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback
Jim Miller9f0753f2015-03-23 23:59:22 -07001152 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -07001153
1154 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -07001155 public void onAuthenticationFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001156 handleFingerprintAuthFailed();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001157 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001158
1159 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -07001160 public void onAuthenticationSucceeded(AuthenticationResult result) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001161 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
Jim Miller837fa7e2016-08-08 20:16:22 -07001162 handleFingerprintAuthenticated(result.getUserId());
Nick Desaulniers1d396752016-07-25 15:05:33 -07001163 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -07001164 }
1165
1166 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -07001167 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001168 handleFingerprintHelp(helpMsgId, helpString.toString());
Jim Miller9f0753f2015-03-23 23:59:22 -07001169 }
1170
1171 @Override
1172 public void onAuthenticationError(int errMsgId, CharSequence errString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001173 handleFingerprintError(errMsgId, errString.toString());
1174 }
1175
1176 @Override
1177 public void onAuthenticationAcquired(int acquireInfo) {
1178 handleFingerprintAcquired(acquireInfo);
Jim Millerf41fc962014-06-18 16:33:51 -07001179 }
1180 };
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001181
Lucas Dupin3d053532019-01-29 12:35:22 -08001182 @VisibleForTesting
1183 FaceManager.AuthenticationCallback mFaceAuthenticationCallback
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001184 = new FaceManager.AuthenticationCallback() {
1185
1186 @Override
1187 public void onAuthenticationFailed() {
1188 handleFaceAuthFailed();
1189 }
1190
1191 @Override
1192 public void onAuthenticationSucceeded(FaceManager.AuthenticationResult result) {
1193 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
1194 handleFaceAuthenticated(result.getUserId());
1195 Trace.endSection();
1196 }
1197
1198 @Override
1199 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
1200 handleFaceHelp(helpMsgId, helpString.toString());
1201 }
1202
1203 @Override
1204 public void onAuthenticationError(int errMsgId, CharSequence errString) {
1205 handleFaceError(errMsgId, errString.toString());
1206 }
1207
1208 @Override
1209 public void onAuthenticationAcquired(int acquireInfo) {
1210 handleFaceAcquired(acquireInfo);
1211 }
1212 };
1213
Jim Miller9f0753f2015-03-23 23:59:22 -07001214 private CancellationSignal mFingerprintCancelSignal;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001215 private CancellationSignal mFaceCancelSignal;
Jim Miller9f0753f2015-03-23 23:59:22 -07001216 private FingerprintManager mFpm;
Kevin Chynb7b54a62018-09-28 18:48:12 -07001217 private FaceManager mFaceManager;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001218
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001219 /**
Jim Miller47088bb2009-11-24 00:40:16 -08001220 * When we receive a
1221 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -07001222 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001223 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -08001224 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001225 */
Jim Miller52a61332014-11-12 19:29:51 -08001226 private static class SimData {
1227 public State simState;
1228 public int slotId;
1229 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001230
Jim Miller52a61332014-11-12 19:29:51 -08001231 SimData(State state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -08001232 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -08001233 slotId = slot;
1234 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -08001235 }
1236
Jim Miller52a61332014-11-12 19:29:51 -08001237 static SimData fromIntent(Intent intent) {
1238 State state;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001239 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
1240 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
1241 }
Wink Savillea639b312012-07-10 12:37:54 -07001242 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
Jayachandran Cbd481352019-05-21 16:02:23 -07001243 int slotId = intent.getIntExtra(PhoneConstants.PHONE_KEY, 0);
Jim Miller52a61332014-11-12 19:29:51 -08001244 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
Wink Savilled09c4ca2014-11-22 10:08:16 -08001245 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea639b312012-07-10 12:37:54 -07001246 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -07001247 final String absentReason = intent
Wink Savillea639b312012-07-10 12:37:54 -07001248 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -07001249
Wink Savillea639b312012-07-10 12:37:54 -07001250 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -07001251 absentReason)) {
Wink Savillea639b312012-07-10 12:37:54 -07001252 state = IccCardConstants.State.PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -07001253 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001254 state = IccCardConstants.State.ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -07001255 }
Wink Savillea639b312012-07-10 12:37:54 -07001256 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
1257 state = IccCardConstants.State.READY;
1258 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001259 final String lockedReason = intent
Wink Savillea639b312012-07-10 12:37:54 -07001260 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
1261 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
1262 state = IccCardConstants.State.PIN_REQUIRED;
1263 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
1264 state = IccCardConstants.State.PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001265 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001266 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001267 }
Wink Savillea639b312012-07-10 12:37:54 -07001268 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
1269 state = IccCardConstants.State.NETWORK_LOCKED;
Wileen Chiu6b8b22e2014-10-29 22:48:21 +05301270 } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
1271 state = IccCardConstants.State.CARD_IO_ERROR;
Jim Miller109f1fd2012-09-19 20:44:16 -07001272 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
1273 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
1274 // This is required because telephony doesn't return to "READY" after
1275 // these state transitions. See bug 7197471.
1276 state = IccCardConstants.State.READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001277 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001278 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001279 }
Jim Miller52a61332014-11-12 19:29:51 -08001280 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001281 }
1282
Jim Millerd72d5ac2015-09-29 18:55:32 -07001283 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001284 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -08001285 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001286 }
1287 }
1288
Adrian Roos12c1ef52014-06-04 13:54:08 +02001289 public static class BatteryStatus {
Adrian Roos7b043112015-07-10 13:00:33 -07001290 public static final int CHARGING_UNKNOWN = -1;
1291 public static final int CHARGING_SLOWLY = 0;
1292 public static final int CHARGING_REGULAR = 1;
1293 public static final int CHARGING_FAST = 2;
1294
Jim Miller16464b82011-10-20 21:10:13 -07001295 public final int status;
1296 public final int level;
1297 public final int plugged;
1298 public final int health;
Adrian Roos0c859ae2015-11-23 16:47:50 -08001299 public final int maxChargingWattage;
1300 public BatteryStatus(int status, int level, int plugged, int health,
1301 int maxChargingWattage) {
Jim Miller16464b82011-10-20 21:10:13 -07001302 this.status = status;
1303 this.level = level;
1304 this.plugged = plugged;
1305 this.health = health;
Adrian Roos0c859ae2015-11-23 16:47:50 -08001306 this.maxChargingWattage = maxChargingWattage;
Jim Miller16464b82011-10-20 21:10:13 -07001307 }
1308
Jim Millerbbf1a742012-07-17 18:30:30 -07001309 /**
Brian Muramatsua92a01b2012-09-05 21:54:39 -07001310 * Determine whether the device is plugged in (USB, power, or wireless).
Jim Millerbbf1a742012-07-17 18:30:30 -07001311 * @return true if the device is plugged in.
1312 */
Adrian Roosad3bc7f2014-10-30 18:29:38 +01001313 public boolean isPluggedIn() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001314 return plugged == BatteryManager.BATTERY_PLUGGED_AC
Brian Muramatsua92a01b2012-09-05 21:54:39 -07001315 || plugged == BatteryManager.BATTERY_PLUGGED_USB
1316 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Jim Millerbbf1a742012-07-17 18:30:30 -07001317 }
1318
1319 /**
Beverly2034c832018-03-19 11:18:51 -04001320 * Determine whether the device is plugged in (USB, power).
1321 * @return true if the device is plugged in wired (as opposed to wireless)
1322 */
1323 public boolean isPluggedInWired() {
1324 return plugged == BatteryManager.BATTERY_PLUGGED_AC
1325 || plugged == BatteryManager.BATTERY_PLUGGED_USB;
1326 }
1327
1328 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001329 * Whether or not the device is charged. Note that some devices never return 100% for
1330 * battery level, so this allows either battery level or status to determine if the
1331 * battery is charged.
1332 * @return true if the device is charged
1333 */
1334 public boolean isCharged() {
1335 return status == BATTERY_STATUS_FULL || level >= 100;
1336 }
1337
1338 /**
1339 * Whether battery is low and needs to be charged.
1340 * @return true if battery is low
1341 */
1342 public boolean isBatteryLow() {
1343 return level < LOW_BATTERY_THRESHOLD;
1344 }
1345
Adrian Roos7b043112015-07-10 13:00:33 -07001346 public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
Adrian Roos0c859ae2015-11-23 16:47:50 -08001347 return maxChargingWattage <= 0 ? CHARGING_UNKNOWN :
1348 maxChargingWattage < slowThreshold ? CHARGING_SLOWLY :
1349 maxChargingWattage > fastThreshold ? CHARGING_FAST :
Adrian Roos7b043112015-07-10 13:00:33 -07001350 CHARGING_REGULAR;
1351 }
Lucas Dupin3fcdd472018-01-19 19:06:45 -08001352
1353 @Override
1354 public String toString() {
1355 return "BatteryStatus{status=" + status + ",level=" + level + ",plugged=" + plugged
1356 + ",health=" + health + ",maxChargingWattage=" + maxChargingWattage + "}";
1357 }
Jim Miller16464b82011-10-20 21:10:13 -07001358 }
1359
Lucas Dupin3d053532019-01-29 12:35:22 -08001360 public static class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
1361 private final Consumer<Integer> mStrongAuthRequiredChangedCallback;
1362
1363 public StrongAuthTracker(Context context,
1364 Consumer<Integer> strongAuthRequiredChangedCallback) {
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001365 super(context);
Lucas Dupin3d053532019-01-29 12:35:22 -08001366 mStrongAuthRequiredChangedCallback = strongAuthRequiredChangedCallback;
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001367 }
Adrian Roosb5e47222015-08-14 15:53:06 -07001368
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001369 public boolean isUnlockingWithBiometricAllowed() {
Adrian Roosb5e47222015-08-14 15:53:06 -07001370 int userId = getCurrentUser();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001371 return isBiometricAllowedForUser(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -07001372 }
1373
1374 public boolean hasUserAuthenticatedSinceBoot() {
1375 int userId = getCurrentUser();
1376 return (getStrongAuthForUser(userId)
1377 & STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
1378 }
1379
1380 @Override
1381 public void onStrongAuthRequiredChanged(int userId) {
Lucas Dupin3d053532019-01-29 12:35:22 -08001382 mStrongAuthRequiredChangedCallback.accept(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -07001383 }
1384 }
1385
Jim Millerdcb3d842012-08-23 19:18:12 -07001386 public static KeyguardUpdateMonitor getInstance(Context context) {
1387 if (sInstance == null) {
1388 sInstance = new KeyguardUpdateMonitor(context);
1389 }
1390 return sInstance;
1391 }
1392
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001393 protected void handleStartedWakingUp() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001394 Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001395 updateBiometricListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001396 final int count = mCallbacks.size();
1397 for (int i = 0; i < count; i++) {
1398 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1399 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001400 cb.onStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -07001401 }
1402 }
Nick Desaulniers1d396752016-07-25 15:05:33 -07001403 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -07001404 }
1405
Jorim Jaggi95e40382015-09-16 15:53:42 -07001406 protected void handleStartedGoingToSleep(int arg1) {
Curtis Belmonte15114ab2019-08-16 14:32:14 -07001407 mLockIconPressed = false;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001408 clearBiometricRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -07001409 final int count = mCallbacks.size();
1410 for (int i = 0; i < count; i++) {
1411 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1412 if (cb != null) {
Jorim Jaggi95e40382015-09-16 15:53:42 -07001413 cb.onStartedGoingToSleep(arg1);
1414 }
1415 }
1416 mGoingToSleep = true;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001417 updateBiometricListeningState();
Jorim Jaggi95e40382015-09-16 15:53:42 -07001418 }
1419
1420 protected void handleFinishedGoingToSleep(int arg1) {
1421 mGoingToSleep = false;
1422 final int count = mCallbacks.size();
1423 for (int i = 0; i < count; i++) {
1424 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1425 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001426 cb.onFinishedGoingToSleep(arg1);
Jim Miller20daffd2013-10-07 14:59:53 -07001427 }
1428 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001429 updateBiometricListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001430 }
1431
Jorim Jaggif1518da2015-07-30 11:56:36 -07001432 private void handleScreenTurnedOn() {
1433 final int count = mCallbacks.size();
1434 for (int i = 0; i < count; i++) {
1435 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1436 if (cb != null) {
1437 cb.onScreenTurnedOn();
1438 }
1439 }
1440 }
1441
1442 private void handleScreenTurnedOff() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001443 mHardwareFingerprintUnavailableRetryCount = 0;
1444 mHardwareFaceUnavailableRetryCount = 0;
Jorim Jaggif1518da2015-07-30 11:56:36 -07001445 final int count = mCallbacks.size();
1446 for (int i = 0; i < count; i++) {
1447 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1448 if (cb != null) {
1449 cb.onScreenTurnedOff();
1450 }
1451 }
1452 }
1453
Selim Cinek99415392016-09-09 14:58:41 -07001454 private void handleDreamingStateChanged(int dreamStart) {
1455 final int count = mCallbacks.size();
Kevin Chyn36778ff2017-09-07 19:55:38 -07001456 mIsDreaming = dreamStart == 1;
Selim Cinek99415392016-09-09 14:58:41 -07001457 for (int i = 0; i < count; i++) {
1458 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1459 if (cb != null) {
Kevin Chyn36778ff2017-09-07 19:55:38 -07001460 cb.onDreamingStateChanged(mIsDreaming);
Selim Cinek99415392016-09-09 14:58:41 -07001461 }
1462 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001463 updateBiometricListeningState();
Selim Cinek99415392016-09-09 14:58:41 -07001464 }
1465
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001466 private void handleUserInfoChanged(int userId) {
1467 for (int i = 0; i < mCallbacks.size(); i++) {
1468 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1469 if (cb != null) {
1470 cb.onUserInfoChanged(userId);
1471 }
1472 }
1473 }
1474
Jorim Jaggidadafd42016-09-30 07:20:25 -07001475 private void handleUserUnlocked() {
1476 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1477 for (int i = 0; i < mCallbacks.size(); i++) {
1478 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1479 if (cb != null) {
1480 cb.onUserUnlocked();
1481 }
1482 }
1483 }
1484
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001485 @VisibleForTesting
1486 protected KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001487 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -08001488 mSubscriptionManager = SubscriptionManager.from(context);
Michael Jurkafff56142012-11-28 16:51:00 -08001489 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Lucas Dupin3d053532019-01-29 12:35:22 -08001490 mStrongAuthTracker = new StrongAuthTracker(context, this::notifyStrongAuthStateChanged);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001491
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001492 // Since device can't be un-provisioned, we only need to register a content observer
1493 // to update mDeviceProvisioned when we are...
1494 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001495 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001496 }
Jim Miller47088bb2009-11-24 00:40:16 -08001497
Jim Millerbbf1a742012-07-17 18:30:30 -07001498 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Adrian Roos7b043112015-07-10 13:00:33 -07001499 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001500
Jim Millerbbf1a742012-07-17 18:30:30 -07001501 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001502 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001503 filter.addAction(Intent.ACTION_TIME_TICK);
1504 filter.addAction(Intent.ACTION_TIME_CHANGED);
1505 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
1506 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Jason Monk052082c2015-06-11 11:35:23 -04001507 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001508 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Etan Cohen47051d82015-07-06 16:19:04 -07001509 filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Fabian Kozynskiccde55d2019-06-26 10:06:09 -04001510 filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -08001511 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -08001512 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Alex Chauff7653d2018-02-01 17:18:08 +00001513 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jason Monk7bb59302018-05-10 19:38:18 -07001514 context.registerReceiver(mBroadcastReceiver, filter, null, mHandler);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001515
Adam Cohenc276e822012-11-08 13:01:08 -08001516 final IntentFilter bootCompleteFilter = new IntentFilter();
1517 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1518 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
Jason Monk7bb59302018-05-10 19:38:18 -07001519 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter, null, mHandler);
Adam Cohenc276e822012-11-08 13:01:08 -08001520
Adrian Roos48c796c2014-09-01 14:59:23 +02001521 final IntentFilter allUserFilter = new IntentFilter();
1522 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
1523 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
1524 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
1525 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
1526 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001527 allUserFilter.addAction(ACTION_USER_UNLOCKED);
Adrian Roos48c796c2014-09-01 14:59:23 +02001528 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Jason Monk7bb59302018-05-10 19:38:18 -07001529 null, mHandler);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001530
Wink Saville071743f2015-01-12 17:11:04 -08001531 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001532 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001533 ActivityManager.getService().registerUserSwitchObserver(
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001534 new UserSwitchObserver() {
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001535 @Override
1536 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001537 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001538 newUserId, 0, reply));
1539 }
1540 @Override
1541 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001542 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +02001543 newUserId, 0));
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001544 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001545 }, TAG);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001546 } catch (RemoteException e) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001547 e.rethrowAsRuntimeException();
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001548 }
Adrian Roos46842d92014-03-27 14:58:03 +01001549
Jorim Jaggi237b0612015-05-01 14:28:49 -07001550 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
1551 mTrustManager.registerTrustListener(this);
Michal Karpinskic52f8672016-11-18 11:32:45 +00001552 mLockPatternUtils = new LockPatternUtils(context);
1553 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Jim Millerf41fc962014-06-18 16:33:51 -07001554
Kevin Chyn36778ff2017-09-07 19:55:38 -07001555 mDreamManager = IDreamManager.Stub.asInterface(
1556 ServiceManager.getService(DreamService.DREAM_SERVICE));
1557
Jorim Jaggi3f124262016-11-22 13:45:17 +01001558 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
1559 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
1560 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001561 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
Kevin Chynb7b54a62018-09-28 18:48:12 -07001562 mFaceManager = (FaceManager) context.getSystemService(Context.FACE_SERVICE);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001563 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07001564
1565 if (mFpm != null || mFaceManager != null) {
1566 mBiometricManager = context.getSystemService(BiometricManager.class);
1567 mBiometricManager.registerEnabledOnKeyguardCallback(mBiometricEnabledCallback);
1568 }
1569
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001570 updateBiometricListeningState();
Jorim Jaggi3a464782015-08-28 16:59:13 -07001571 if (mFpm != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001572 mFpm.addLockoutResetCallback(mFingerprintLockoutResetCallback);
1573 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07001574 if (mFaceManager != null) {
1575 mFaceManager.addLockoutResetCallback(mFaceLockoutResetCallback);
Jorim Jaggi3a464782015-08-28 16:59:13 -07001576 }
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001577
Winson Chung2cf6ad82017-11-09 17:36:59 -08001578 ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001579 mUserManager = context.getSystemService(UserManager.class);
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001580 mIsPrimaryUser = mUserManager.isPrimaryUser();
Alex Chauff7653d2018-02-01 17:18:08 +00001581 mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
1582 mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
Bill Linef81cbd2018-07-05 17:48:49 +08001583 updateAirplaneModeState();
Fabian Kozynskiccde55d2019-06-26 10:06:09 -04001584
1585 TelephonyManager telephony =
1586 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
1587 if (telephony != null) {
1588 telephony.listen(mPhoneStateListener, LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
1589 }
Bill Linef81cbd2018-07-05 17:48:49 +08001590 }
1591
1592 private void updateAirplaneModeState() {
1593 // ACTION_AIRPLANE_MODE_CHANGED do not broadcast if device set AirplaneMode ON and boot
1594 if (!WirelessUtils.isAirplaneModeOn(mContext)
1595 || mHandler.hasMessages(MSG_AIRPLANE_MODE_CHANGED)) {
1596 return;
1597 }
1598 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Jorim Jaggiea657062015-04-28 13:45:11 -07001599 }
1600
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001601 private void updateBiometricListeningState() {
1602 updateFingerprintListeningState();
1603 updateFaceListeningState();
1604 }
1605
Jorim Jaggiea657062015-04-28 13:45:11 -07001606 private void updateFingerprintListeningState() {
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001607 // If this message exists, we should not authenticate again until this message is
1608 // consumed by the handler
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001609 if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001610 return;
1611 }
Kevin Chyn0c45b072017-04-24 16:27:11 -07001612 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
Jorim Jaggiea657062015-04-28 13:45:11 -07001613 boolean shouldListenForFingerprint = shouldListenForFingerprint();
Adrian Roos2aaf9442018-11-20 16:57:33 +01001614 boolean runningOrRestarting = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING
1615 || mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING;
1616 if (runningOrRestarting && !shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001617 stopListeningForFingerprint();
Adrian Roos2aaf9442018-11-20 16:57:33 +01001618 } else if (!runningOrRestarting && shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001619 startListeningForFingerprint();
1620 }
1621 }
1622
Lucas Dupin3d053532019-01-29 12:35:22 -08001623 /**
Lucas Dupine0516d52019-02-05 17:54:06 -05001624 * Called whenever passive authentication is requested or aborted by a sensor.
1625 * @param active If the interrupt started or ended.
Lucas Dupin3d053532019-01-29 12:35:22 -08001626 */
Lucas Dupine0516d52019-02-05 17:54:06 -05001627 public void onAuthInterruptDetected(boolean active) {
1628 if (DEBUG) Log.d(TAG, "onAuthInterruptDetected(" + active + ")");
1629 if (mAuthInterruptActive == active) {
1630 return;
1631 }
1632 mAuthInterruptActive = active;
Lucas Dupin3d053532019-01-29 12:35:22 -08001633 updateFaceListeningState();
1634 }
1635
Lucas Dupin8f3faac2019-03-12 15:28:49 -07001636 /**
1637 * Requests face authentication if we're on a state where it's allowed.
1638 * This will re-trigger auth in case it fails.
1639 */
1640 public void requestFaceAuth() {
1641 if (DEBUG) Log.d(TAG, "requestFaceAuth()");
1642 updateFaceListeningState();
1643 }
1644
Lucas Dupinccf67212019-08-07 12:53:02 -07001645 /**
1646 * In case face auth is running, cancel it.
1647 */
1648 public void cancelFaceAuth() {
1649 stopListeningForFace();
1650 }
1651
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001652 private void updateFaceListeningState() {
1653 // If this message exists, we should not authenticate again until this message is
1654 // consumed by the handler
1655 if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
1656 return;
1657 }
1658 mHandler.removeCallbacks(mRetryFaceAuthentication);
1659 boolean shouldListenForFace = shouldListenForFace();
1660 if (mFaceRunningState == BIOMETRIC_STATE_RUNNING && !shouldListenForFace) {
1661 stopListeningForFace();
1662 } else if (mFaceRunningState != BIOMETRIC_STATE_RUNNING
1663 && shouldListenForFace) {
1664 startListeningForFace();
1665 }
1666 }
1667
Kevin Chyn129f60f2017-08-11 17:24:42 -07001668 private boolean shouldListenForFingerprintAssistant() {
1669 return mAssistantVisible && mKeyguardOccluded
1670 && !mUserFingerprintAuthenticated.get(getCurrentUser(), false)
1671 && !mUserHasTrust.get(getCurrentUser(), false);
1672 }
1673
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001674 private boolean shouldListenForFaceAssistant() {
1675 return mAssistantVisible && mKeyguardOccluded
1676 && !mUserFaceAuthenticated.get(getCurrentUser(), false)
1677 && !mUserHasTrust.get(getCurrentUser(), false);
1678 }
1679
Jorim Jaggiea657062015-04-28 13:45:11 -07001680 private boolean shouldListenForFingerprint() {
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001681 // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
1682 // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
1683 final boolean shouldListen = (mKeyguardIsVisible || !mDeviceInteractive ||
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001684 (mBouncer && !mKeyguardGoingAway) || mGoingToSleep ||
Kevin Chyn36778ff2017-09-07 19:55:38 -07001685 shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming))
Lucas Dupinc12fad32019-05-14 20:59:17 +00001686 && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser())
Kevin Chyn225eea72019-03-06 16:42:00 -08001687 && (!mKeyguardGoingAway || !mDeviceInteractive) && mIsPrimaryUser;
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001688 return shouldListen;
Jim Miller9f0753f2015-03-23 23:59:22 -07001689 }
1690
Lucas Dupin62622222019-08-29 14:46:29 -07001691 /**
1692 * If face auth is allows to scan on this exact moment.
1693 */
1694 public boolean shouldListenForFace() {
Lucas Dupin3d053532019-01-29 12:35:22 -08001695 final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep;
1696 final int user = getCurrentUser();
Robert Snoeberger5dcdf352019-06-24 11:28:28 -04001697 final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user);
1698 final boolean isLockOutOrLockDown =
Lucas Dupin8eec2682019-07-01 16:41:17 -07001699 containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_LOCKOUT)
1700 || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
1701 || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
1702 final boolean isEncryptedOrTimedOut =
1703 containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT)
1704 || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
Lucas Dupin9e484aa2019-06-24 13:38:00 -07001705
Lucas Dupin4befb742019-07-01 11:31:31 -07001706 boolean canBypass = mKeyguardBypassController != null
1707 && mKeyguardBypassController.canBypass();
Lucas Dupin9e484aa2019-06-24 13:38:00 -07001708 // There's no reason to ask the HAL for authentication when the user can dismiss the
1709 // bouncer, unless we're bypassing and need to auto-dismiss the lock screen even when
1710 // TrustAgents or biometrics are keeping the device unlocked.
Lucas Dupin4befb742019-07-01 11:31:31 -07001711 boolean becauseCannotSkipBouncer = !getUserCanSkipBouncer(user) || canBypass;
Lucas Dupin9e484aa2019-06-24 13:38:00 -07001712
Lucas Dupin8eec2682019-07-01 16:41:17 -07001713 // Scan even when encrypted or timeout to show a preemptive bouncer when bypassing.
1714 // Lockout/lockdown modes shouldn't scan, since they are more explicit.
1715 boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass && !mBouncer)
1716 && !isLockOutOrLockDown;
1717
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001718 // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
1719 // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
Lucas Dupine0516d52019-02-05 17:54:06 -05001720 return (mBouncer || mAuthInterruptActive || awakeKeyguard || shouldListenForFaceAssistant())
Lucas Dupin9e484aa2019-06-24 13:38:00 -07001721 && !mSwitchingUser && !isFaceDisabled(user) && becauseCannotSkipBouncer
Lucas Dupin7d95f152019-07-17 16:25:54 -07001722 && !mKeyguardGoingAway && mFaceSettingEnabledForUser.get(user) && !mLockIconPressed
Lucas Dupin8eec2682019-07-01 16:41:17 -07001723 && strongAuthAllowsScanning && mIsPrimaryUser
1724 && !mSecureCameraLaunched;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001725 }
1726
Lucas Dupinca88e5f2019-05-14 16:11:08 -07001727 /**
1728 * Whenever the lock icon is long pressed, disabling trust agents.
1729 * This means that we cannot auth passively (face) until the user presses power.
1730 */
1731 public void onLockIconPressed() {
1732 mLockIconPressed = true;
1733 mUserFaceAuthenticated.put(getCurrentUser(), false);
1734 updateFaceListeningState();
1735 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001736
Jim Millerce7eb6d2015-04-03 19:29:13 -07001737 private void startListeningForFingerprint() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001738 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING) {
1739 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001740 return;
1741 }
Adrian Roos2aaf9442018-11-20 16:57:33 +01001742 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1743 // Waiting for restart via handleFingerprintError().
1744 return;
1745 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001746 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Lucas Dupin8f3faac2019-03-12 15:28:49 -07001747 int userId = getCurrentUser();
Jorim Jaggi71448a72015-08-18 19:49:04 -07001748 if (isUnlockWithFingerprintPossible(userId)) {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001749 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001750 mFingerprintCancelSignal.cancel();
1751 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001752 mFingerprintCancelSignal = new CancellationSignal();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001753 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mFingerprintAuthenticationCallback,
1754 null, userId);
1755 setFingerprintRunningState(BIOMETRIC_STATE_RUNNING);
1756 }
1757 }
1758
1759 private void startListeningForFace() {
1760 if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING) {
1761 setFaceRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);
1762 return;
1763 }
1764 if (DEBUG) Log.v(TAG, "startListeningForFace()");
Lucas Dupin8f3faac2019-03-12 15:28:49 -07001765 int userId = getCurrentUser();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001766 if (isUnlockWithFacePossible(userId)) {
1767 if (mFaceCancelSignal != null) {
1768 mFaceCancelSignal.cancel();
1769 }
1770 mFaceCancelSignal = new CancellationSignal();
Kevin Chynb7b54a62018-09-28 18:48:12 -07001771 mFaceManager.authenticate(null, mFaceCancelSignal, 0,
Kevin Chyn8d2694a2019-04-11 18:30:40 -07001772 mFaceAuthenticationCallback, null, userId);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001773 setFaceRunningState(BIOMETRIC_STATE_RUNNING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001774 }
1775 }
1776
Lucas Dupin8d48fc42019-04-25 14:34:12 -07001777 /**
1778 * If biometrics hardware is available, not disabled, and user has enrolled templates.
1779 * This does NOT check if the device is encrypted or in lockdown.
1780 *
1781 * @param userId User that's trying to unlock.
1782 * @return {@code true} if possible.
1783 */
1784 public boolean isUnlockingWithBiometricsPossible(int userId) {
1785 return isUnlockWithFacePossible(userId) || isUnlockWithFingerprintPossible(userId);
1786 }
1787
1788 private boolean isUnlockWithFingerprintPossible(int userId) {
Selim Cinek3122fa82015-06-18 01:38:59 -07001789 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
1790 && mFpm.getEnrolledFingerprints(userId).size() > 0;
1791 }
1792
Lucas Dupin4c507042019-07-22 16:47:34 -07001793 private boolean isUnlockWithFacePossible(int userId) {
1794 return isFaceAuthEnabledForUser(userId) && !isFaceDisabled(userId);
1795 }
1796
Lucas Dupin7156bc72019-05-03 19:37:39 -07001797 /**
Lucas Dupin7d95f152019-07-17 16:25:54 -07001798 * If face hardware is available, user has enrolled and enabled auth via setting.
Lucas Dupin7156bc72019-05-03 19:37:39 -07001799 */
Lucas Dupin4c507042019-07-22 16:47:34 -07001800 public boolean isFaceAuthEnabledForUser(int userId) {
Kevin Chynb7b54a62018-09-28 18:48:12 -07001801 return mFaceManager != null && mFaceManager.isHardwareDetected()
Lucas Dupin7d95f152019-07-17 16:25:54 -07001802 && mFaceManager.hasEnrolledTemplates(userId)
1803 && mFaceSettingEnabledForUser.get(userId);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001804 }
1805
Jorim Jaggiea657062015-04-28 13:45:11 -07001806 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001807 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001808 if (mFingerprintRunningState == BIOMETRIC_STATE_RUNNING) {
Kevin Chyn2fefd462017-04-28 12:18:19 -07001809 if (mFingerprintCancelSignal != null) {
1810 mFingerprintCancelSignal.cancel();
1811 mFingerprintCancelSignal = null;
1812 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001813 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001814 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001815 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1816 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING);
1817 }
1818 }
1819
1820 private void stopListeningForFace() {
1821 if (DEBUG) Log.v(TAG, "stopListeningForFace()");
1822 if (mFaceRunningState == BIOMETRIC_STATE_RUNNING) {
1823 if (mFaceCancelSignal != null) {
1824 mFaceCancelSignal.cancel();
1825 mFaceCancelSignal = null;
1826 }
1827 setFaceRunningState(BIOMETRIC_STATE_CANCELLING);
1828 }
1829 if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1830 setFaceRunningState(BIOMETRIC_STATE_CANCELLING);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001831 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001832 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001833
Michael Jurkafff56142012-11-28 16:51:00 -08001834 private boolean isDeviceProvisionedInSettingsDb() {
1835 return Settings.Global.getInt(mContext.getContentResolver(),
1836 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1837 }
1838
Jim Millerbbf1a742012-07-17 18:30:30 -07001839 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -08001840 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001841 @Override
1842 public void onChange(boolean selfChange) {
1843 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -08001844 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001845 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001846 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001847 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001848 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001849 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001850 };
1851
1852 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -07001853 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -08001854 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -07001855
1856 // prevent a race condition between where we check the flag and where we register the
1857 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -08001858 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001859 if (provisioned != mDeviceProvisioned) {
1860 mDeviceProvisioned = provisioned;
1861 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001862 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001863 }
1864 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001865 }
1866
Jim Millerbbf1a742012-07-17 18:30:30 -07001867 /**
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001868 * Update the state whether Keyguard currently has a lockscreen wallpaper.
1869 *
1870 * @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper.
1871 */
1872 public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001873 checkIsHandlerThread();
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001874 if (hasLockscreenWallpaper != mHasLockscreenWallpaper) {
1875 mHasLockscreenWallpaper = hasLockscreenWallpaper;
1876 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1877 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1878 if (cb != null) {
1879 cb.onHasLockscreenWallpaperChanged(hasLockscreenWallpaper);
1880 }
1881 }
1882 }
1883 }
1884
1885 /**
1886 * @return Whether Keyguard has a lockscreen wallpaper.
1887 */
1888 public boolean hasLockscreenWallpaper() {
1889 return mHasLockscreenWallpaper;
1890 }
1891
1892 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001893 * Handle {@link #MSG_DPM_STATE_CHANGED}
1894 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001895 private void handleDevicePolicyManagerStateChanged() {
Adrian Roos733b6632015-08-21 14:32:35 -07001896 updateFingerprintListeningState();
Jim Millerdcb3d842012-08-23 19:18:12 -07001897 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1898 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1899 if (cb != null) {
1900 cb.onDevicePolicyManagerStateChanged();
1901 }
Jim Millerb0304762012-03-13 20:01:25 -07001902 }
1903 }
1904
Jim Millerbbf1a742012-07-17 18:30:30 -07001905 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001906 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -07001907 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001908 private void handleUserSwitching(int userId, IRemoteCallback reply) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001909 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001910 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1911 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001912 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -07001913 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001914 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001915 try {
1916 reply.sendResult(null);
1917 } catch (RemoteException e) {
1918 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001919 }
1920
Jim Millerbbf1a742012-07-17 18:30:30 -07001921 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001922 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
1923 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001924 private void handleUserSwitchComplete(int userId) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001925 for (int i = 0; i < mCallbacks.size(); i++) {
1926 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1927 if (cb != null) {
1928 cb.onUserSwitchComplete(userId);
1929 }
1930 }
1931 }
1932
1933 /**
Jim Miller90873d52013-09-26 18:11:38 -07001934 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
1935 * keyguard crashes sometime after boot, then it will never receive this
1936 * broadcast and hence not handle the event. This method is ultimately called by
1937 * PhoneWindowManager in this case.
1938 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001939 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001940 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -07001941 }
1942
1943 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001944 * Handle {@link #MSG_BOOT_COMPLETED}
1945 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001946 private void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001947 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001948 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001949 for (int i = 0; i < mCallbacks.size(); i++) {
1950 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1951 if (cb != null) {
1952 cb.onBootCompleted();
1953 }
1954 }
1955 }
1956
1957 /**
Jim Miller5ecd8112013-01-09 18:50:26 -08001958 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001959 * destroyed.
1960 */
1961 public boolean hasBootCompleted() {
1962 return mBootCompleted;
1963 }
1964
1965 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001966 * Handle {@link #MSG_DEVICE_PROVISIONED}
1967 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001968 private void handleDeviceProvisioned() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001969 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001970 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1971 if (cb != null) {
1972 cb.onDeviceProvisioned();
1973 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001974 }
Michael Jurkafff56142012-11-28 16:51:00 -08001975 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001976 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -08001977 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
1978 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001979 }
1980 }
1981
Jim Millerbbf1a742012-07-17 18:30:30 -07001982 /**
1983 * Handle {@link #MSG_PHONE_STATE_CHANGED}
1984 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001985 private void handlePhoneStateChanged(String newState) {
Jim Millerc23024d2010-02-24 15:37:00 -08001986 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001987 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
1988 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
1989 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
1990 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
1991 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
1992 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
1993 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001994 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001995 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1996 if (cb != null) {
1997 cb.onPhoneStateChanged(mPhoneState);
1998 }
Jim Millerc23024d2010-02-24 15:37:00 -08001999 }
2000 }
2001
Jim Millerbbf1a742012-07-17 18:30:30 -07002002 /**
2003 * Handle {@link #MSG_RINGER_MODE_CHANGED}
2004 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02002005 private void handleRingerModeChange(int mode) {
Jim Miller47088bb2009-11-24 00:40:16 -08002006 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07002007 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -07002008 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002009 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2010 if (cb != null) {
2011 cb.onRingerModeChanged(mode);
2012 }
Jim Miller47088bb2009-11-24 00:40:16 -08002013 }
2014 }
2015
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002016 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002017 * Handle {@link #MSG_TIME_UPDATE}
2018 */
2019 private void handleTimeUpdate() {
2020 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07002021 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002022 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2023 if (cb != null) {
2024 cb.onTimeChanged();
2025 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002026 }
2027 }
2028
2029 /**
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05002030 * Handle (@line #MSG_TIMEZONE_UPDATE}
2031 */
2032 private void handleTimeZoneUpdate(String timeZone) {
2033 if (DEBUG) Log.d(TAG, "handleTimeZoneUpdate");
2034 for (int i = 0; i < mCallbacks.size(); i++) {
2035 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2036 if (cb != null) {
2037 cb.onTimeZoneChanged(TimeZone.getTimeZone(timeZone));
2038 // Also notify callbacks about time change to remain compatible.
2039 cb.onTimeChanged();
2040 }
2041 }
2042 }
2043
2044 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002045 * Handle {@link #MSG_BATTERY_UPDATE}
2046 */
Jim Millerbbf1a742012-07-17 18:30:30 -07002047 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002048 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07002049 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
2050 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07002051 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002052 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002053 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2054 if (cb != null) {
2055 cb.onRefreshBatteryInfo(status);
2056 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002057 }
2058 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002059 }
2060
2061 /**
Bill Linef81cbd2018-07-05 17:48:49 +08002062 * Handle Telephony status during Boot for CarrierText display policy
2063 */
2064 @VisibleForTesting
2065 void updateTelephonyCapable(boolean capable){
2066 if (capable == mTelephonyCapable) {
2067 return;
2068 }
2069 mTelephonyCapable = capable;
2070 for (WeakReference<KeyguardUpdateMonitorCallback> ref : mCallbacks) {
2071 KeyguardUpdateMonitorCallback cb = ref.get();
2072 if (cb != null) {
2073 cb.onTelephonyCapable(mTelephonyCapable);
2074 }
2075 }
2076 }
2077
2078 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002079 * Handle {@link #MSG_SIM_STATE_CHANGE}
2080 */
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08002081 @VisibleForTesting
Adrian Roos30a2ae62018-04-25 19:09:50 +02002082 void handleSimStateChange(int subId, int slotId, State state) {
2083 checkIsHandlerThread();
Jim Miller52a61332014-11-12 19:29:51 -08002084 if (DEBUG_SIM_STATES) {
2085 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
2086 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002087 }
2088
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002089 boolean becameAbsent = false;
Wink Savillea54bf652014-12-11 13:37:50 -08002090 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08002091 Log.w(TAG, "invalid subId in handleSimStateChange()");
andychou695a7602019-05-16 23:14:00 +08002092 /* Only handle No SIM(ABSENT) and Card Error(CARD_IO_ERROR) due to
2093 * handleServiceStateChange() handle other case */
Bill Linef81cbd2018-07-05 17:48:49 +08002094 if (state == State.ABSENT) {
2095 updateTelephonyCapable(true);
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002096 // Even though the subscription is not valid anymore, we need to notify that the
2097 // SIM card was removed so we can update the UI.
2098 becameAbsent = true;
Brad Ebingere6c6f722018-12-20 21:11:44 -08002099 for (SimData data : mSimDatas.values()) {
2100 // Set the SIM state of all SimData associated with that slot to ABSENT se we
2101 // do not move back into PIN/PUK locked and not detect the change below.
2102 if (data.slotId == slotId) {
2103 data.simState = State.ABSENT;
2104 }
2105 }
andychou695a7602019-05-16 23:14:00 +08002106 } else if (state == State.CARD_IO_ERROR) {
2107 updateTelephonyCapable(true);
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002108 } else {
2109 return;
Bill Linef81cbd2018-07-05 17:48:49 +08002110 }
Jim Miller52a61332014-11-12 19:29:51 -08002111 }
2112
2113 SimData data = mSimDatas.get(subId);
2114 final boolean changed;
2115 if (data == null) {
2116 data = new SimData(state, slotId, subId);
2117 mSimDatas.put(subId, data);
2118 changed = true; // no data yet; force update
2119 } else {
2120 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
2121 data.simState = state;
2122 data.subId = subId;
2123 data.slotId = slotId;
2124 }
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002125 if ((changed || becameAbsent) && state != State.UNKNOWN) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002126 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002127 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2128 if (cb != null) {
Jim Miller52a61332014-11-12 19:29:51 -08002129 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07002130 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002131 }
2132 }
2133 }
2134
Jim Millerbbf1a742012-07-17 18:30:30 -07002135 /**
Etan Cohen47051d82015-07-06 16:19:04 -07002136 * Handle {@link #MSG_SERVICE_STATE_CHANGE}
2137 */
Bill Linef81cbd2018-07-05 17:48:49 +08002138 @VisibleForTesting
2139 void handleServiceStateChange(int subId, ServiceState serviceState) {
Etan Cohen47051d82015-07-06 16:19:04 -07002140 if (DEBUG) {
2141 Log.d(TAG,
2142 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
2143 }
2144
2145 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2146 Log.w(TAG, "invalid subId in handleServiceStateChange()");
2147 return;
Bill Linef81cbd2018-07-05 17:48:49 +08002148 } else {
2149 updateTelephonyCapable(true);
Etan Cohen47051d82015-07-06 16:19:04 -07002150 }
2151
2152 mServiceStates.put(subId, serviceState);
2153
2154 for (int j = 0; j < mCallbacks.size(); j++) {
2155 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
2156 if (cb != null) {
2157 cb.onRefreshCarrierInfo();
2158 }
2159 }
2160 }
2161
Lucas Dupinf8463ee2018-06-11 16:18:15 -07002162 public boolean isKeyguardVisible() {
2163 return mKeyguardIsVisible;
2164 }
2165
Etan Cohen47051d82015-07-06 16:19:04 -07002166 /**
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002167 * Notifies that the visibility state of Keyguard has changed.
2168 *
2169 * <p>Needs to be called from the main thread.
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002170 */
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002171 public void onKeyguardVisibilityChanged(boolean showing) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002172 checkIsHandlerThread();
Kevin Chynb4514d22019-04-15 13:47:25 -07002173 Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002174 mKeyguardIsVisible = showing;
Kevin Chyn6951d3d2019-06-10 14:07:13 -07002175
2176 if (showing) {
2177 mSecureCameraLaunched = false;
2178 }
2179
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002180 for (int i = 0; i < mCallbacks.size(); i++) {
2181 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2182 if (cb != null) {
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002183 cb.onKeyguardVisibilityChangedRaw(showing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002184 }
2185 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002186 updateBiometricListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002187 }
2188
Brian Colonna7fce3802013-09-17 15:51:32 -04002189 /**
Selim Cinek1fcafc42015-07-20 14:39:25 -07002190 * Handle {@link #MSG_KEYGUARD_RESET}
2191 */
2192 private void handleKeyguardReset() {
2193 if (DEBUG) Log.d(TAG, "handleKeyguardReset");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002194 updateBiometricListeningState();
Jorim Jaggi031f7952016-09-01 16:39:26 -07002195 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
2196 }
2197
2198 private boolean resolveNeedsSlowUnlockTransition() {
2199 if (mUserManager.isUserUnlocked(getCurrentUser())) {
2200 return false;
2201 }
2202 Intent homeIntent = new Intent(Intent.ACTION_MAIN)
2203 .addCategory(Intent.CATEGORY_HOME);
2204 ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(homeIntent,
2205 0 /* flags */);
2206 return FALLBACK_HOME_COMPONENT.equals(resolveInfo.getComponentInfo().getComponentName());
Selim Cinek1fcafc42015-07-20 14:39:25 -07002207 }
2208
2209 /**
Adrian Roosb6011622014-05-14 15:52:53 +02002210 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
2211 * @see #sendKeyguardBouncerChanged(boolean)
2212 */
2213 private void handleKeyguardBouncerChanged(int bouncer) {
2214 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
2215 boolean isBouncer = (bouncer == 1);
2216 mBouncer = isBouncer;
Kevin Chynd0381892019-07-11 16:25:36 -07002217
2218 if (isBouncer) {
2219 // If the bouncer is shown, always clear this flag. This can happen in the following
2220 // situations: 1) Default camera with SHOW_WHEN_LOCKED is not chosen yet. 2) Secure
2221 // camera requests dismiss keyguard (tapping on photos for example). When these happen,
2222 // face auth should resume.
2223 mSecureCameraLaunched = false;
2224 }
2225
Adrian Roosb6011622014-05-14 15:52:53 +02002226 for (int i = 0; i < mCallbacks.size(); i++) {
2227 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2228 if (cb != null) {
2229 cb.onKeyguardBouncerChanged(isBouncer);
2230 }
2231 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002232 updateBiometricListeningState();
Adrian Roosb6011622014-05-14 15:52:53 +02002233 }
2234
2235 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04002236 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
2237 */
2238 private void handleReportEmergencyCallAction() {
2239 for (int i = 0; i < mCallbacks.size(); i++) {
2240 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2241 if (cb != null) {
2242 cb.onEmergencyCallAction();
2243 }
2244 }
2245 }
2246
Lucas Dupin4272f442018-01-13 22:00:35 -08002247 private boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002248 final boolean nowPluggedIn = current.isPluggedIn();
2249 final boolean wasPluggedIn = old.isPluggedIn();
Lucas Dupin4272f442018-01-13 22:00:35 -08002250 final boolean stateChangedWhilePluggedIn = wasPluggedIn && nowPluggedIn
Jim Miller16464b82011-10-20 21:10:13 -07002251 && (old.status != current.status);
2252
2253 // change in plug state is always interesting
2254 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002255 return true;
2256 }
2257
Lucas Dupin3fcdd472018-01-19 19:06:45 -08002258 // change in battery level
2259 if (old.level != current.level) {
Jim Miller16464b82011-10-20 21:10:13 -07002260 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002261 }
Adrian Roos76dc5a52015-07-21 16:20:36 -07002262
2263 // change in charging current while plugged in
Adrian Roos0c859ae2015-11-23 16:47:50 -08002264 if (nowPluggedIn && current.maxChargingWattage != old.maxChargingWattage) {
Adrian Roos76dc5a52015-07-21 16:20:36 -07002265 return true;
2266 }
2267
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002268 return false;
2269 }
2270
2271 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07002272 * Remove the given observer's callback.
2273 *
Jim Miller6212cc02012-09-05 17:35:31 -07002274 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002275 */
Jim Miller6212cc02012-09-05 17:35:31 -07002276 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002277 checkIsHandlerThread();
Jim Miller6212cc02012-09-05 17:35:31 -07002278 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
2279 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
2280 if (mCallbacks.get(i).get() == callback) {
2281 mCallbacks.remove(i);
2282 }
2283 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002284 }
2285
2286 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002287 * Register to receive notifications about general keyguard information
2288 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07002289 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002290 */
Jim Millerbbf1a742012-07-17 18:30:30 -07002291 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002292 checkIsHandlerThread();
Jim Miller6212cc02012-09-05 17:35:31 -07002293 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
2294 // Prevent adding duplicate callbacks
2295 for (int i = 0; i < mCallbacks.size(); i++) {
2296 if (mCallbacks.get(i).get() == callback) {
2297 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
2298 new Exception("Called by"));
2299 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07002300 }
2301 }
Jim Miller6212cc02012-09-05 17:35:31 -07002302 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
2303 removeCallback(null); // remove unused references
2304 sendUpdates(callback);
2305 }
2306
Lucas Dupin9e484aa2019-06-24 13:38:00 -07002307 public void setKeyguardBypassController(KeyguardBypassController keyguardBypassController) {
2308 mKeyguardBypassController = keyguardBypassController;
2309 }
2310
Lucas Dupinc12fad32019-05-14 20:59:17 +00002311 public boolean isSwitchingUser() {
2312 return mSwitchingUser;
2313 }
2314
Adrian Roos30a2ae62018-04-25 19:09:50 +02002315 @AnyThread
Evan Rosky18396452016-07-27 15:19:37 -07002316 public void setSwitchingUser(boolean switching) {
Lucas Dupinc12fad32019-05-14 20:59:17 +00002317 mSwitchingUser = switching;
Selim Cinekbbe19242017-12-08 15:42:08 -08002318 // Since this comes in on a binder thread, we need to post if first
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002319 mHandler.post(mUpdateBiometricListeningState);
Evan Rosky18396452016-07-27 15:19:37 -07002320 }
2321
Jim Miller6212cc02012-09-05 17:35:31 -07002322 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
2323 // Notify listener of the current state
2324 callback.onRefreshBatteryInfo(mBatteryStatus);
2325 callback.onTimeChanged();
2326 callback.onRingerModeChanged(mRingMode);
2327 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05002328 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07002329 callback.onClockVisibilityChanged();
Lucas Dupin16cfe452018-02-08 13:14:50 -08002330 callback.onKeyguardVisibilityChangedRaw(mKeyguardIsVisible);
Bill Linef81cbd2018-07-05 17:48:49 +08002331 callback.onTelephonyCapable(mTelephonyCapable);
Jim Miller52a61332014-11-12 19:29:51 -08002332 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
2333 final SimData state = data.getValue();
2334 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
2335 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002336 }
2337
Selim Cinek1fcafc42015-07-20 14:39:25 -07002338 public void sendKeyguardReset() {
2339 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
2340 }
2341
Adrian Roosb6011622014-05-14 15:52:53 +02002342 /**
2343 * @see #handleKeyguardBouncerChanged(int)
2344 */
2345 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
2346 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
2347 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
2348 message.arg1 = showingBouncer ? 1 : 0;
2349 message.sendToTarget();
2350 }
2351
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002352 /**
Jim Miller90d5d462011-11-17 16:57:01 -08002353 * 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 -08002354 * have the information earlier than waiting for the intent
2355 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08002356 *
2357 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
2358 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002359 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02002360 @MainThread
Jim Miller52a61332014-11-12 19:29:51 -08002361 public void reportSimUnlocked(int subId) {
2362 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
Sanket Padawe7e460252017-03-10 16:18:20 -08002363 int slotId = SubscriptionManager.getSlotIndex(subId);
Jim Miller52a61332014-11-12 19:29:51 -08002364 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002365 }
2366
Brian Colonna7fce3802013-09-17 15:51:32 -04002367 /**
2368 * Report that the emergency call button has been pressed and the emergency dialer is
2369 * about to be displayed.
2370 *
2371 * @param bypassHandler runs immediately.
2372 *
2373 * NOTE: Must be called from UI thread if bypassHandler == true.
2374 */
2375 public void reportEmergencyCallAction(boolean bypassHandler) {
2376 if (!bypassHandler) {
2377 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
2378 } else {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002379 checkIsHandlerThread();
Brian Colonna7fce3802013-09-17 15:51:32 -04002380 handleReportEmergencyCallAction();
2381 }
2382 }
2383
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002384 /**
2385 * @return Whether the device is provisioned (whether they have gone through
2386 * the setup wizard)
2387 */
2388 public boolean isDeviceProvisioned() {
2389 return mDeviceProvisioned;
2390 }
2391
Kensuke Matsui21d1bf12017-03-14 13:27:20 +09002392 public ServiceState getServiceState(int subId) {
2393 return mServiceStates.get(subId);
2394 }
2395
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002396 public void clearBiometricRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07002397 mUserFingerprintAuthenticated.clear();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002398 mUserFaceAuthenticated.clear();
2399 mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FINGERPRINT);
2400 mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FACE);
Aran Ink4c0d5602019-06-21 14:27:32 -04002401
2402 for (int i = 0; i < mCallbacks.size(); i++) {
2403 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2404 if (cb != null) {
2405 cb.onBiometricsCleared();
2406 }
2407 }
Jim Millerf41fc962014-06-18 16:33:51 -07002408 }
2409
Jim Miller52a61332014-11-12 19:29:51 -08002410 public boolean isSimPinVoiceSecure() {
2411 // TODO: only count SIMs that handle voice
2412 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07002413 }
2414
Lucas Dupin7156bc72019-05-03 19:37:39 -07002415 /**
2416 * If any SIM cards are currently secure.
2417 * @see #isSimPinSecure(State)
2418 */
Jim Millerdcb3d842012-08-23 19:18:12 -07002419 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08002420 // True if any SIM is pin secure
2421 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
2422 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
2423 }
2424 return false;
2425 }
2426
Jason Monk9ff69bd2014-12-02 16:43:17 -05002427 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08002428 if (mSimDatas.containsKey(subId)) {
2429 return mSimDatas.get(subId).simState;
2430 } else {
2431 return State.UNKNOWN;
2432 }
2433 }
2434
Winson Chung67f5c8b2018-09-24 12:09:19 -07002435 private final TaskStackChangeListener
2436 mTaskStackListener = new TaskStackChangeListener() {
Kevin Chyn2fefd462017-04-28 12:18:19 -07002437 @Override
2438 public void onTaskStackChangedBackground() {
2439 try {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002440 ActivityManager.StackInfo info = ActivityTaskManager.getService().getStackInfo(
Wale Ogunwale68278562017-09-23 17:13:55 -07002441 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
Kevin Chyn2fefd462017-04-28 12:18:19 -07002442 if (info == null) {
2443 return;
2444 }
2445 mHandler.sendMessage(mHandler.obtainMessage(MSG_ASSISTANT_STACK_CHANGED,
2446 info.visible));
2447 } catch (RemoteException e) {
2448 Log.e(TAG, "unable to check task stack", e);
2449 }
2450 }
2451 };
2452
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002453 /**
Richard Choue0381b82018-04-24 03:48:59 +00002454 * @return true if and only if the state has changed for the specified {@code slotId}
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002455 */
Richard Choue0381b82018-04-24 03:48:59 +00002456 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08002457
2458 // This is awful. It exists because there are two APIs for getting the SIM status
2459 // that don't return the complete set of values and have different types. In Keyguard we
2460 // need IccCardConstants, but TelephonyManager would only give us
2461 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08002462 final TelephonyManager tele = TelephonyManager.from(mContext);
Richard Choue0381b82018-04-24 03:48:59 +00002463 int simState = tele.getSimState(slotId);
2464 State state;
2465 try {
2466 state = State.intToState(simState);
2467 } catch(IllegalArgumentException ex) {
2468 Log.w(TAG, "Unknown sim state: " + simState);
2469 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05002470 }
Richard Choue0381b82018-04-24 03:48:59 +00002471 SimData data = mSimDatas.get(subId);
2472 final boolean changed;
2473 if (data == null) {
2474 data = new SimData(state, slotId, subId);
2475 mSimDatas.put(subId, data);
2476 changed = true; // no data yet; force update
2477 } else {
2478 changed = data.simState != state;
2479 data.simState = state;
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002480 }
Richard Choue0381b82018-04-24 03:48:59 +00002481 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07002482 }
2483
Lucas Dupin7156bc72019-05-03 19:37:39 -07002484 /**
2485 * If the {@code state} is currently requiring a SIM PIN, PUK, or is disabled.
2486 */
Jim Millerdcb3d842012-08-23 19:18:12 -07002487 public static boolean isSimPinSecure(IccCardConstants.State state) {
Lucas Dupin7156bc72019-05-03 19:37:39 -07002488 return (state == IccCardConstants.State.PIN_REQUIRED
2489 || state == IccCardConstants.State.PUK_REQUIRED
2490 || state == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07002491 }
Jim Miller8f09fd22013-03-14 19:04:28 -07002492
2493 public DisplayClientState getCachedDisplayClientState() {
2494 return mDisplayClientState;
2495 }
Jim Miller20daffd2013-10-07 14:59:53 -07002496
2497 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
2498 // (KeyguardViewMediator, KeyguardHostView)
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002499 public void dispatchStartedWakingUp() {
2500 synchronized (this) {
2501 mDeviceInteractive = true;
2502 }
2503 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
2504 }
2505
Jorim Jaggi95e40382015-09-16 15:53:42 -07002506 public void dispatchStartedGoingToSleep(int why) {
2507 mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
2508 }
2509
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002510 public void dispatchFinishedGoingToSleep(int why) {
2511 synchronized(this) {
2512 mDeviceInteractive = false;
2513 }
2514 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
2515 }
2516
Jim Miller20daffd2013-10-07 14:59:53 -07002517 public void dispatchScreenTurnedOn() {
2518 synchronized (this) {
2519 mScreenOn = true;
2520 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07002521 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
Jim Miller20daffd2013-10-07 14:59:53 -07002522 }
2523
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002524 public void dispatchScreenTurnedOff() {
Jim Miller20daffd2013-10-07 14:59:53 -07002525 synchronized(this) {
2526 mScreenOn = false;
2527 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07002528 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
Jim Miller20daffd2013-10-07 14:59:53 -07002529 }
2530
Selim Cinek99415392016-09-09 14:58:41 -07002531 public void dispatchDreamingStarted() {
2532 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 1, 0));
2533 }
2534
2535 public void dispatchDreamingStopped() {
2536 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 0, 0));
2537 }
2538
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002539 public boolean isDeviceInteractive() {
2540 return mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -07002541 }
Jim Miller52a61332014-11-12 19:29:51 -08002542
Jorim Jaggi95e40382015-09-16 15:53:42 -07002543 public boolean isGoingToSleep() {
2544 return mGoingToSleep;
2545 }
2546
Jim Miller52a61332014-11-12 19:29:51 -08002547 /**
2548 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
2549 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08002550 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08002551 */
2552 public int getNextSubIdForState(State state) {
2553 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08002554 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08002555 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
2556 for (int i = 0; i < list.size(); i++) {
2557 final SubscriptionInfo info = list.get(i);
2558 final int id = info.getSubscriptionId();
Sanket Padawe7e460252017-03-10 16:18:20 -08002559 int slotId = SubscriptionManager.getSlotIndex(id);
Jim Miller52a61332014-11-12 19:29:51 -08002560 if (state == getSimState(id) && bestSlotId > slotId ) {
2561 resultId = id;
2562 bestSlotId = slotId;
2563 }
2564 }
2565 return resultId;
2566 }
2567
2568 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
2569 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
2570 for (int i = 0; i < list.size(); i++) {
2571 SubscriptionInfo info = list.get(i);
2572 if (subId == info.getSubscriptionId()) return info;
2573 }
2574 return null; // not found
2575 }
Jason Monkab525272015-07-13 17:02:49 -04002576
Alex Chauff7653d2018-02-01 17:18:08 +00002577 /**
2578 * @return a cached version of DevicePolicyManager.isLogoutEnabled()
2579 */
2580 public boolean isLogoutEnabled() {
2581 return mLogoutEnabled;
2582 }
2583
2584 private void updateLogoutEnabled() {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002585 checkIsHandlerThread();
Alex Chauff7653d2018-02-01 17:18:08 +00002586 boolean logoutEnabled = mDevicePolicyManager.isLogoutEnabled();
2587 if (mLogoutEnabled != logoutEnabled) {
2588 mLogoutEnabled = logoutEnabled;
2589 for (int i = 0; i < mCallbacks.size(); i++) {
2590 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2591 if (cb != null) {
2592 cb.onLogoutEnabledChanged();
2593 }
2594 }
2595 }
2596 }
2597
Adrian Roos30a2ae62018-04-25 19:09:50 +02002598 private void checkIsHandlerThread() {
2599 if (sDisableHandlerCheckForTesting) {
2600 return;
2601 }
2602 if (!mHandler.getLooper().isCurrentThread()) {
2603 Log.wtf(TAG, "must call on mHandler's thread "
2604 + mHandler.getLooper().getThread() + ", not " + Thread.currentThread());
2605 }
2606 }
2607
2608 /**
2609 * Turn off the handler check for testing.
2610 *
2611 * This is necessary because currently tests are not too careful about which thread they call
2612 * into this class on.
2613 *
2614 * Note that this must be called before scheduling any work involving KeyguardUpdateMonitor
2615 * instances.
2616 *
2617 * TODO: fix the tests and remove this.
2618 */
2619 @VisibleForTesting
2620 public static void disableHandlerCheckForTesting(Instrumentation instrumentation) {
2621 Preconditions.checkNotNull(instrumentation, "Must only call this method in tests!");
2622 // Don't need synchronization here *if* the callers follow the contract and call this only
2623 // before scheduling work for KeyguardUpdateMonitor on other threads, because the scheduling
2624 // of that work forces a happens-before relationship.
2625 sDisableHandlerCheckForTesting = true;
2626 }
2627
Jason Monkab525272015-07-13 17:02:49 -04002628 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2629 pw.println("KeyguardUpdateMonitor state:");
2630 pw.println(" SIM States:");
2631 for (SimData data : mSimDatas.values()) {
2632 pw.println(" " + data.toString());
2633 }
2634 pw.println(" Subs:");
2635 if (mSubscriptionInfo != null) {
2636 for (int i = 0; i < mSubscriptionInfo.size(); i++) {
2637 pw.println(" " + mSubscriptionInfo.get(i));
2638 }
2639 }
2640 pw.println(" Service states:");
2641 for (int subId : mServiceStates.keySet()) {
2642 pw.println(" " + subId + "=" + mServiceStates.get(subId));
2643 }
Jim Millerd72d5ac2015-09-29 18:55:32 -07002644 if (mFpm != null && mFpm.isHardwareDetected()) {
2645 final int userId = ActivityManager.getCurrentUser();
2646 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
2647 pw.println(" Fingerprint state (user=" + userId + ")");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002648 pw.println(" allowed=" + isUnlockingWithBiometricAllowed());
Jim Millerd72d5ac2015-09-29 18:55:32 -07002649 pw.println(" auth'd=" + mUserFingerprintAuthenticated.get(userId));
2650 pw.println(" authSinceBoot="
2651 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
2652 pw.println(" disabled(DPM)=" + isFingerprintDisabled(userId));
2653 pw.println(" possible=" + isUnlockWithFingerprintPossible(userId));
Adrian Roos2aaf9442018-11-20 16:57:33 +01002654 pw.println(" listening: actual=" + mFingerprintRunningState
2655 + " expected=" + (shouldListenForFingerprint() ? 1 : 0));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002656 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002657 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
2658 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07002659 if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002660 final int userId = ActivityManager.getCurrentUser();
2661 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
2662 pw.println(" Face authentication state (user=" + userId + ")");
2663 pw.println(" allowed=" + isUnlockingWithBiometricAllowed());
2664 pw.println(" auth'd=" + mUserFaceAuthenticated.get(userId));
2665 pw.println(" authSinceBoot="
2666 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
2667 pw.println(" disabled(DPM)=" + isFaceDisabled(userId));
2668 pw.println(" possible=" + isUnlockWithFacePossible(userId));
2669 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
2670 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
Lucas Dupin7d95f152019-07-17 16:25:54 -07002671 pw.println(" enabledByUser=" + mFaceSettingEnabledForUser.get(userId));
Kevin Chynd0381892019-07-11 16:25:36 -07002672 pw.println(" mSecureCameraLaunched=" + mSecureCameraLaunched);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002673 }
Jason Monkab525272015-07-13 17:02:49 -04002674 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002675}