blob: f771cc6796363ef7063a991469bd0fdd46c2f9aa [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;
Lucas Dupin6c6d5732019-08-27 17:36:05 -070021import static android.content.Intent.ACTION_USER_REMOVED;
22import static android.content.Intent.ACTION_USER_STOPPED;
Jorim Jaggidadafd42016-09-30 07:20:25 -070023import static android.content.Intent.ACTION_USER_UNLOCKED;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070024import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
Fabian Kozynskiccde55d2019-06-26 10:06:09 -040025import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070026
Lucas Dupin8eec2682019-07-01 16:41:17 -070027import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_BOOT;
28import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
29import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT;
30import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
31import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
Lucas Dupin8968f6a2019-08-09 17:41:15 -070032import static com.android.systemui.DejankUtils.whitelistIpcs;
Lucas Dupin8eec2682019-07-01 16:41:17 -070033
Adrian Roos30a2ae62018-04-25 19:09:50 +020034import android.annotation.AnyThread;
35import android.annotation.MainThread;
Jorim Jaggiccdfa932015-04-13 16:29:48 -070036import android.app.ActivityManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070037import android.app.ActivityTaskManager;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020038import android.app.AlarmManager;
Jim Miller8f09fd22013-03-14 19:04:28 -070039import android.app.PendingIntent;
Sudheer Shanka2c4522c2016-08-27 20:53:28 -070040import android.app.UserSwitchObserver;
Jim Millerb0304762012-03-13 20:01:25 -070041import android.app.admin.DevicePolicyManager;
Adrian Roos46842d92014-03-27 14:58:03 +010042import android.app.trust.TrustManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080043import android.content.BroadcastReceiver;
Jorim Jaggi031f7952016-09-01 16:39:26 -070044import android.content.ComponentName;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080045import android.content.Context;
46import android.content.Intent;
47import android.content.IntentFilter;
Adrian Roosca8a2162017-08-17 19:00:58 +020048import android.content.pm.IPackageManager;
Jorim Jaggi031f7952016-09-01 16:39:26 -070049import android.content.pm.PackageManager;
50import android.content.pm.ResolveInfo;
Lucas Dupinf2c53502019-10-03 13:56:18 -070051import android.content.pm.UserInfo;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080052import android.database.ContentObserver;
Kevin Chynb7b54a62018-09-28 18:48:12 -070053import android.hardware.biometrics.BiometricManager;
Kevin Chyn56233ab2018-09-20 17:10:57 -070054import android.hardware.biometrics.BiometricSourceType;
Kevin Chynb7b54a62018-09-28 18:48:12 -070055import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
Gilad Brettercb51b8b2018-03-22 17:04:51 +020056import android.hardware.face.FaceManager;
Jorim Jaggi86bed402015-08-20 18:20:02 -070057import android.hardware.fingerprint.FingerprintManager;
58import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
59import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
Jim Miller9f0753f2015-03-23 23:59:22 -070060import android.os.CancellationSignal;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080061import android.os.Handler;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070062import android.os.IRemoteCallback;
Jason Monk7bb59302018-05-10 19:38:18 -070063import android.os.Looper;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080064import android.os.Message;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070065import android.os.RemoteException;
Adrian Roosca8a2162017-08-17 19:00:58 +020066import android.os.ServiceManager;
Nick Desaulniers1d396752016-07-25 15:05:33 -070067import android.os.Trace;
Amith Yamasanie8e93a12013-05-09 18:12:30 -070068import android.os.UserHandle;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070069import android.os.UserManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080070import android.provider.Settings;
Kevin Chyn36778ff2017-09-07 19:55:38 -070071import android.service.dreams.DreamService;
72import android.service.dreams.IDreamManager;
Malcolm Chen5c63b512019-08-13 13:24:07 -070073import android.telephony.CarrierConfigManager;
Fabian Kozynskiccde55d2019-06-26 10:06:09 -040074import android.telephony.PhoneStateListener;
Etan Cohen47051d82015-07-06 16:19:04 -070075import android.telephony.ServiceState;
Jim Miller52a61332014-11-12 19:29:51 -080076import android.telephony.SubscriptionInfo;
Jim Miller52a61332014-11-12 19:29:51 -080077import android.telephony.SubscriptionManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -080078import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Jim Millerc23024d2010-02-24 15:37:00 -080079import android.telephony.TelephonyManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080080import android.util.Log;
Haining Chenc06c4812020-01-13 20:38:53 -080081import android.util.SparseArray;
Adrian Roos46842d92014-03-27 14:58:03 +010082import android.util.SparseBooleanArray;
83
Fabian Kozynskib6a20372020-04-01 09:36:43 -040084import androidx.lifecycle.Observer;
85
Lucas Dupin7517b5d2017-08-22 12:51:25 -070086import com.android.internal.annotations.VisibleForTesting;
Adrian Roosb5e47222015-08-14 15:53:06 -070087import com.android.internal.widget.LockPatternUtils;
Bill Linef81cbd2018-07-05 17:48:49 +080088import com.android.settingslib.WirelessUtils;
Raff Tsaif4ea5622019-06-26 16:15:21 +080089import com.android.settingslib.fuelgauge.BatteryStatus;
Lucas Dupind236ee32019-10-08 15:33:59 -070090import com.android.systemui.DejankUtils;
Lucas Dupin64171fe2019-10-30 14:28:29 -070091import com.android.systemui.Dumpable;
Hyunyoung Song8f9d34c2019-08-30 14:47:43 -070092import com.android.systemui.R;
Fabian Kozynski5ca7a512019-10-16 19:56:11 +000093import com.android.systemui.broadcast.BroadcastDispatcher;
Haining Chenc06c4812020-01-13 20:38:53 -080094import com.android.systemui.dagger.qualifiers.Background;
Dave Mankoff00e8a2f2019-12-18 16:59:49 -050095import com.android.systemui.dagger.qualifiers.Main;
Ned Burnsaaeb44b2020-02-12 23:48:26 -050096import com.android.systemui.dump.DumpManager;
Curtis Belmonte9dc68152020-05-08 17:12:13 -070097import com.android.systemui.plugins.statusbar.StatusBarStateController;
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;
Curtis Belmonte9dc68152020-05-08 17:12:13 -0700100import com.android.systemui.statusbar.StatusBarState;
Lucas Dupin9e484aa2019-06-24 13:38:00 -0700101import com.android.systemui.statusbar.phone.KeyguardBypassController;
Beverly1467c9e2020-02-18 13:31:29 -0500102import com.android.systemui.util.Assert;
Fabian Kozynskib6a20372020-04-01 09:36:43 -0400103import com.android.systemui.util.RingerModeTracker;
Kevin Chyn1123ba72018-10-26 10:34:06 -0700104
Kevin Chyn36778ff2017-09-07 19:55:38 -0700105import com.google.android.collect.Lists;
106
Jason Monkab525272015-07-13 17:02:49 -0400107import java.io.FileDescriptor;
108import java.io.PrintWriter;
Jim Millerdcb3d842012-08-23 19:18:12 -0700109import java.lang.ref.WeakReference;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800110import java.util.ArrayList;
Jim Miller52a61332014-11-12 19:29:51 -0800111import java.util.HashMap;
112import java.util.List;
Yvonne Jiangb7024a22019-12-05 16:57:08 -0800113import java.util.Map;
Jim Miller52a61332014-11-12 19:29:51 -0800114import java.util.Map.Entry;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500115import java.util.TimeZone;
Haining Chenc06c4812020-01-13 20:38:53 -0800116import java.util.concurrent.Executor;
Lucas Dupin3d053532019-01-29 12:35:22 -0800117import java.util.function.Consumer;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800118
Dave Mankoffe2294692019-08-14 11:53:13 -0400119import javax.inject.Inject;
Lucas Dupinab39e802019-10-08 14:42:00 -0700120import javax.inject.Singleton;
Dave Mankoffe2294692019-08-14 11:53:13 -0400121
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800122/**
123 * Watches for updates that may be interesting to the keyguard, and provides
124 * the up to date information as well as a registration for callbacks that care
125 * to be updated.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800126 */
Lucas Dupinab39e802019-10-08 14:42:00 -0700127@Singleton
Lucas Dupin64171fe2019-10-30 14:28:29 -0700128public class KeyguardUpdateMonitor implements TrustManager.TrustListener, Dumpable {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800129
Jim Millerbbf1a742012-07-17 18:30:30 -0700130 private static final String TAG = "KeyguardUpdateMonitor";
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100131 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller52a61332014-11-12 19:29:51 -0800132 private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700133 private static final boolean DEBUG_FACE = true;
Kevin Chyn505eb892020-03-26 13:07:03 -0700134 private static final boolean DEBUG_SPEW = false;
Jim Millerbbf1a742012-07-17 18:30:30 -0700135 private static final int LOW_BATTERY_THRESHOLD = 20;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800136
Jorim Jaggie7b12522014-08-06 16:41:21 +0200137 private static final String ACTION_FACE_UNLOCK_STARTED
138 = "com.android.facelock.FACE_UNLOCK_STARTED";
139 private static final String ACTION_FACE_UNLOCK_STOPPED
140 = "com.android.facelock.FACE_UNLOCK_STOPPED";
141
Jim Millerbbf1a742012-07-17 18:30:30 -0700142 // Callback messages
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800143 private static final int MSG_TIME_UPDATE = 301;
144 private static final int MSG_BATTERY_UPDATE = 302;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800145 private static final int MSG_SIM_STATE_CHANGE = 304;
Jim Miller47088bb2009-11-24 00:40:16 -0800146 private static final int MSG_RINGER_MODE_CHANGED = 305;
Jim Millerc23024d2010-02-24 15:37:00 -0800147 private static final int MSG_PHONE_STATE_CHANGED = 306;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700148 private static final int MSG_DEVICE_PROVISIONED = 308;
Jim Miller57375342012-09-09 15:20:31 -0700149 private static final int MSG_DPM_STATE_CHANGED = 309;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500150 private static final int MSG_USER_SWITCHING = 310;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700151 private static final int MSG_KEYGUARD_RESET = 312;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500152 private static final int MSG_USER_SWITCH_COMPLETE = 314;
Jim Millerf41fc962014-06-18 16:33:51 -0700153 private static final int MSG_USER_INFO_CHANGED = 317;
154 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700155 private static final int MSG_STARTED_WAKING_UP = 319;
156 private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700157 private static final int MSG_STARTED_GOING_TO_SLEEP = 321;
Adrian Roosb6011622014-05-14 15:52:53 +0200158 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700159 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
160 private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
Jason Monk052082c2015-06-11 11:35:23 -0400161 private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
Etan Cohen47051d82015-07-06 16:19:04 -0700162 private static final int MSG_SERVICE_STATE_CHANGE = 330;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700163 private static final int MSG_SCREEN_TURNED_ON = 331;
164 private static final int MSG_SCREEN_TURNED_OFF = 332;
Selim Cinek99415392016-09-09 14:58:41 -0700165 private static final int MSG_DREAMING_STATE_CHANGED = 333;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700166 private static final int MSG_USER_UNLOCKED = 334;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700167 private static final int MSG_ASSISTANT_STACK_CHANGED = 335;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200168 private static final int MSG_BIOMETRIC_AUTHENTICATION_CONTINUE = 336;
Alex Chauff7653d2018-02-01 17:18:08 +0000169 private static final int MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED = 337;
Bill Linef81cbd2018-07-05 17:48:49 +0800170 private static final int MSG_TELEPHONY_CAPABLE = 338;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500171 private static final int MSG_TIMEZONE_UPDATE = 339;
Lucas Dupin6c6d5732019-08-27 17:36:05 -0700172 private static final int MSG_USER_STOPPED = 340;
173 private static final int MSG_USER_REMOVED = 341;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800174
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200175 /** Biometric authentication state: Not listening. */
176 private static final int BIOMETRIC_STATE_STOPPED = 0;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700177
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200178 /** Biometric authentication state: Listening. */
179 private static final int BIOMETRIC_STATE_RUNNING = 1;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700180
181 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200182 * Biometric authentication: Cancelling and waiting for the relevant biometric service to
Jorim Jaggi86bed402015-08-20 18:20:02 -0700183 * send us the confirmation that cancellation has happened.
184 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200185 private static final int BIOMETRIC_STATE_CANCELLING = 2;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700186
187 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200188 * Biometric state: During cancelling we got another request to start listening, so when we
Jorim Jaggi86bed402015-08-20 18:20:02 -0700189 * receive the cancellation done signal, we should start listening again.
190 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200191 private static final int BIOMETRIC_STATE_CANCELLING_RESTARTING = 3;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700192
Lucas Dupin51996bb2019-05-16 17:56:43 -0700193 private static final int BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED = -1;
194 public static final int BIOMETRIC_HELP_FACE_NOT_RECOGNIZED = -2;
195
Adrian Roos0c859ae2015-11-23 16:47:50 -0800196 private static final int DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT = 5000000;
joshmccloskey7dee4542019-07-31 18:35:33 -0700197 /**
198 * If no cancel signal has been received after this amount of time, set the biometric running
199 * state to stopped to allow Keyguard to retry authentication.
200 */
201 private static final int DEFAULT_CANCEL_SIGNAL_TIMEOUT = 3000;
Adrian Roos0c859ae2015-11-23 16:47:50 -0800202
Jorim Jaggi031f7952016-09-01 16:39:26 -0700203 private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName(
204 "com.android.settings", "com.android.settings.FallbackHome");
205
Adrian Roosca8a2162017-08-17 19:00:58 +0200206
207 /**
208 * If true, the system is in the half-boot-to-decryption-screen state.
209 * Prudently disable lockscreen.
210 */
211 public static final boolean CORE_APPS_ONLY;
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700212
Adrian Roosca8a2162017-08-17 19:00:58 +0200213 static {
214 try {
215 CORE_APPS_ONLY = IPackageManager.Stub.asInterface(
216 ServiceManager.getService("package")).isOnlyCoreApps();
217 } catch (RemoteException e) {
218 throw e.rethrowFromSystemServer();
219 }
220 }
221
Jim Millerbbf1a742012-07-17 18:30:30 -0700222 private final Context mContext;
Kevin Chynfdfd2d32019-03-01 14:52:15 -0800223 private final boolean mIsPrimaryUser;
Curtis Belmonte9dc68152020-05-08 17:12:13 -0700224 private final StatusBarStateController mStatusBarStateController;
Lucas Dupin10960bd2019-09-27 16:08:32 -0700225 HashMap<Integer, SimData> mSimDatas = new HashMap<>();
Etan Cohen47051d82015-07-06 16:19:04 -0700226 HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700227
Jim Millerbbf1a742012-07-17 18:30:30 -0700228 private int mRingMode;
229 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400230 private boolean mKeyguardIsVisible;
Kevin Chyn8ae64b52020-04-06 15:48:49 -0700231 private boolean mCredentialAttempted;
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700232 private boolean mKeyguardGoingAway;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700233 private boolean mGoingToSleep;
Adrian Roosb6011622014-05-14 15:52:53 +0200234 private boolean mBouncer;
Lucas Dupine0516d52019-02-05 17:54:06 -0500235 private boolean mAuthInterruptActive;
Jorim Jaggi031f7952016-09-01 16:39:26 -0700236 private boolean mNeedsSlowUnlockTransition;
Jorim Jaggid11d1a92016-08-16 16:02:32 -0700237 private boolean mHasLockscreenWallpaper;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700238 private boolean mAssistantVisible;
239 private boolean mKeyguardOccluded;
Kevin Chyn6951d3d2019-06-10 14:07:13 -0700240 private boolean mSecureCameraLaunched;
Bill Linef81cbd2018-07-05 17:48:49 +0800241 @VisibleForTesting
242 protected boolean mTelephonyCapable;
Jim Millerbbf1a742012-07-17 18:30:30 -0700243
Jim Millerdcb3d842012-08-23 19:18:12 -0700244 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700245 private boolean mDeviceProvisioned;
246
Jim Millerdcb3d842012-08-23 19:18:12 -0700247 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700248 private BatteryStatus mBatteryStatus;
249
Lucas Dupin3d053532019-01-29 12:35:22 -0800250 @VisibleForTesting
251 protected StrongAuthTracker mStrongAuthTracker;
Jim Millerbbf1a742012-07-17 18:30:30 -0700252
Jim Miller6212cc02012-09-05 17:35:31 -0700253 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700254 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800255 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700256
Brian Colonnaa5239892013-04-15 11:45:40 -0400257 private boolean mSwitchingUser;
258
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700259 private boolean mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -0700260 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800261 private SubscriptionManager mSubscriptionManager;
262 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700263 private TrustManager mTrustManager;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700264 private UserManager mUserManager;
Lucas Dupin9e484aa2019-06-24 13:38:00 -0700265 private KeyguardBypassController mKeyguardBypassController;
Fabian Kozynskib6a20372020-04-01 09:36:43 -0400266 private RingerModeTracker mRingerModeTracker;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200267 private int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
268 private int mFaceRunningState = BIOMETRIC_STATE_STOPPED;
Michal Karpinskic52f8672016-11-18 11:32:45 +0000269 private LockPatternUtils mLockPatternUtils;
Kevin Chyn36778ff2017-09-07 19:55:38 -0700270 private final IDreamManager mDreamManager;
271 private boolean mIsDreaming;
Alex Chauff7653d2018-02-01 17:18:08 +0000272 private final DevicePolicyManager mDevicePolicyManager;
Beverly4e7dd9a2020-02-28 17:04:21 -0500273 private final BroadcastDispatcher mBroadcastDispatcher;
Alex Chauff7653d2018-02-01 17:18:08 +0000274 private boolean mLogoutEnabled;
Lucas Dupinca88e5f2019-05-14 16:11:08 -0700275 // If the user long pressed the lock icon, disabling face auth for the current session.
276 private boolean mLockIconPressed;
Malcolm Chen5c63b512019-08-13 13:24:07 -0700277 private int mActiveMobileDataSubscription = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Haining Chenc06c4812020-01-13 20:38:53 -0800278 private final Executor mBackgroundExecutor;
Jim Miller20daffd2013-10-07 14:59:53 -0700279
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700280 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200281 * Short delay before restarting biometric authentication after a successful try
282 * This should be slightly longer than the time between on<biometric>Authenticated
283 * (e.g. onFingerprintAuthenticated) and setKeyguardGoingAway(true).
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700284 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200285 private static final int BIOMETRIC_CONTINUE_DELAY_MS = 500;
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700286
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700287 // If the HAL dies or is unable to authenticate, keyguard should retry after a short delay
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200288 private int mHardwareFingerprintUnavailableRetryCount = 0;
289 private int mHardwareFaceUnavailableRetryCount = 0;
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700290 private static final int HAL_ERROR_RETRY_TIMEOUT = 500; // ms
291 private static final int HAL_ERROR_RETRY_MAX = 10;
Kevin Chyn0c45b072017-04-24 16:27:11 -0700292
joshmccloskey7dee4542019-07-31 18:35:33 -0700293 private final Runnable mCancelNotReceived = new Runnable() {
294 @Override
295 public void run() {
296 Log.w(TAG, "Cancel not received, transitioning to STOPPED");
297 mFingerprintRunningState = mFaceRunningState = BIOMETRIC_STATE_STOPPED;
298 updateBiometricListeningState();
299 }
300 };
301
Dave Mankoffe2294692019-08-14 11:53:13 -0400302 private final Handler mHandler;
Jim Millerbbf1a742012-07-17 18:30:30 -0700303
Fabian Kozynskib6a20372020-04-01 09:36:43 -0400304 private final Observer<Integer> mRingerModeObserver = new Observer<Integer>() {
305 @Override
306 public void onChanged(Integer ringer) {
307 mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED, ringer, 0).sendToTarget();
308 }
309 };
310
Lucas Dupin7d95f152019-07-17 16:25:54 -0700311 private SparseBooleanArray mFaceSettingEnabledForUser = new SparseBooleanArray();
Kevin Chynb7b54a62018-09-28 18:48:12 -0700312 private BiometricManager mBiometricManager;
313 private IBiometricEnabledOnKeyguardCallback mBiometricEnabledCallback =
314 new IBiometricEnabledOnKeyguardCallback.Stub() {
Dave Mankoff4b0ab652019-08-07 09:49:20 -0400315 @Override
316 public void onChanged(BiometricSourceType type, boolean enabled, int userId)
317 throws RemoteException {
318 if (type == BiometricSourceType.FACE) {
319 mFaceSettingEnabledForUser.put(userId, enabled);
320 updateFaceListeningState();
321 }
322 }
323 };
Kevin Chynb7b54a62018-09-28 18:48:12 -0700324
Malcolm Chen5c63b512019-08-13 13:24:07 -0700325 @VisibleForTesting
326 public PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
Fabian Kozynskiccde55d2019-06-26 10:06:09 -0400327 @Override
328 public void onActiveDataSubscriptionIdChanged(int subId) {
Malcolm Chen5c63b512019-08-13 13:24:07 -0700329 mActiveMobileDataSubscription = subId;
Fabian Kozynskiccde55d2019-06-26 10:06:09 -0400330 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
331 }
332 };
333
Wink Savilled09c4ca2014-11-22 10:08:16 -0800334 private OnSubscriptionsChangedListener mSubscriptionListener =
335 new OnSubscriptionsChangedListener() {
Dave Mankoff4b0ab652019-08-07 09:49:20 -0400336 @Override
337 public void onSubscriptionsChanged() {
338 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
339 }
340 };
Jim Miller52a61332014-11-12 19:29:51 -0800341
Kevin Chyn505eb892020-03-26 13:07:03 -0700342 @VisibleForTesting
343 static class BiometricAuthenticated {
Haining Chenc06c4812020-01-13 20:38:53 -0800344 private final boolean mAuthenticated;
345 private final boolean mIsStrongBiometric;
346
347 BiometricAuthenticated(boolean authenticated, boolean isStrongBiometric) {
348 this.mAuthenticated = authenticated;
349 this.mIsStrongBiometric = isStrongBiometric;
350 }
351 }
352
Lucas Dupin6c6d5732019-08-27 17:36:05 -0700353 private SparseBooleanArray mUserIsUnlocked = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100354 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200355 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Lucas Dupinf2c53502019-10-03 13:56:18 -0700356 private SparseBooleanArray mUserTrustIsUsuallyManaged = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200357 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Yvonne Jiangb7024a22019-12-05 16:57:08 -0800358 private Map<Integer, Intent> mSecondaryLockscreenRequirement = new HashMap<Integer, Intent>();
Adrian Roos46842d92014-03-27 14:58:03 +0100359
Kevin Chyn505eb892020-03-26 13:07:03 -0700360 @VisibleForTesting
361 SparseArray<BiometricAuthenticated> mUserFingerprintAuthenticated = new SparseArray<>();
362 @VisibleForTesting
363 SparseArray<BiometricAuthenticated> mUserFaceAuthenticated = new SparseArray<>();
364
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700365 private static int sCurrentUser;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200366 private Runnable mUpdateBiometricListeningState = this::updateBiometricListeningState;
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700367
368 public synchronized static void setCurrentUser(int currentUser) {
369 sCurrentUser = currentUser;
370 }
371
372 public synchronized static int getCurrentUser() {
373 return sCurrentUser;
374 }
375
Adrian Roos46842d92014-03-27 14:58:03 +0100376 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700377 public void onTrustChanged(boolean enabled, int userId, int flags) {
Beverly1467c9e2020-02-18 13:31:29 -0500378 Assert.isMainThread();
Adrian Roos46842d92014-03-27 14:58:03 +0100379 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200380 for (int i = 0; i < mCallbacks.size(); i++) {
381 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
382 if (cb != null) {
383 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700384 if (enabled && flags != 0) {
385 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200386 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200387 }
388 }
Adrian Roos46842d92014-03-27 14:58:03 +0100389 }
390
Lucas Dupinef886542018-01-03 16:03:07 -0800391 @Override
392 public void onTrustError(CharSequence message) {
393 dispatchErrorMessage(message);
394 }
395
Adrian Roos30a2ae62018-04-25 19:09:50 +0200396 private void handleSimSubscriptionInfoChanged() {
Beverly1467c9e2020-02-18 13:31:29 -0500397 Assert.isMainThread();
Jim Miller52a61332014-11-12 19:29:51 -0800398 if (DEBUG_SIM_STATES) {
399 Log.v(TAG, "onSubscriptionInfoChanged()");
Amit Mahajan75eab472020-01-29 10:47:48 -0800400 List<SubscriptionInfo> sil = mSubscriptionManager
Sooraj Sasindran40468062020-01-06 19:10:50 -0800401 .getCompleteActiveSubscriptionInfoList();
Wink Savilled09c4ca2014-11-22 10:08:16 -0800402 if (sil != null) {
403 for (SubscriptionInfo subInfo : sil) {
404 Log.v(TAG, "SubInfo:" + subInfo);
405 }
406 } else {
407 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800408 }
409 }
410 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
411
412 // Hack level over 9000: Because the subscription id is not yet valid when we see the
413 // first update in handleSimStateChange, we need to force refresh all all SIM states
414 // so the subscription id for them is consistent.
Richard Choue0381b82018-04-24 03:48:59 +0000415 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
416 for (int i = 0; i < subscriptionInfos.size(); i++) {
417 SubscriptionInfo info = subscriptionInfos.get(i);
418 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
419 if (changed) {
420 changedSubscriptions.add(info);
421 }
422 }
423 for (int i = 0; i < changedSubscriptions.size(); i++) {
424 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800425 for (int j = 0; j < mCallbacks.size(); j++) {
426 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
427 if (cb != null) {
428 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
429 }
430 }
431 }
Dave Mankoff4b0ab652019-08-07 09:49:20 -0400432 callbacksRefreshCarrierInfo();
Jim Miller52a61332014-11-12 19:29:51 -0800433 }
434
Jason Monk052082c2015-06-11 11:35:23 -0400435 private void handleAirplaneModeChanged() {
Dave Mankoff4b0ab652019-08-07 09:49:20 -0400436 callbacksRefreshCarrierInfo();
437 }
438
439 private void callbacksRefreshCarrierInfo() {
Beverly1467c9e2020-02-18 13:31:29 -0500440 Assert.isMainThread();
Dave Mankoff4b0ab652019-08-07 09:49:20 -0400441 for (int i = 0; i < mCallbacks.size(); i++) {
442 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
Jason Monk052082c2015-06-11 11:35:23 -0400443 if (cb != null) {
444 cb.onRefreshCarrierInfo();
445 }
446 }
447 }
448
Malcolm Chen5c63b512019-08-13 13:24:07 -0700449 /**
450 * @return List of SubscriptionInfo records, maybe empty but never null.
451 */
Adrian Roos316bf542016-08-23 17:53:07 +0200452 public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800453 List<SubscriptionInfo> sil = mSubscriptionInfo;
454 if (sil == null || forceReload) {
Sooraj Sasindran40468062020-01-06 19:10:50 -0800455 sil = mSubscriptionManager.getCompleteActiveSubscriptionInfoList();
Wink Savilled09c4ca2014-11-22 10:08:16 -0800456 }
457 if (sil == null) {
Sooraj Sasindran40468062020-01-06 19:10:50 -0800458 // getCompleteActiveSubscriptionInfoList was null callers expect an empty list.
Wink Savilled09c4ca2014-11-22 10:08:16 -0800459 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
460 } else {
461 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800462 }
Malcolm Chen5c63b512019-08-13 13:24:07 -0700463 return new ArrayList<>(mSubscriptionInfo);
464 }
465
466 /**
467 * This method returns filtered list of SubscriptionInfo from {@link #getSubscriptionInfo}.
468 * above. Maybe empty but never null.
469 *
470 * In DSDS mode if both subscriptions are grouped and one is opportunistic, we filter out one
471 * of them based on carrier config. e.g. In this case we should only show one carrier name
472 * on the status bar and quick settings.
473 */
474 public List<SubscriptionInfo> getFilteredSubscriptionInfo(boolean forceReload) {
475 List<SubscriptionInfo> subscriptions = getSubscriptionInfo(false);
Malcolm Chene6befe22020-02-25 13:34:09 -0800476 if (subscriptions.size() == 2) {
Malcolm Chen5c63b512019-08-13 13:24:07 -0700477 SubscriptionInfo info1 = subscriptions.get(0);
478 SubscriptionInfo info2 = subscriptions.get(1);
479 if (info1.getGroupUuid() != null && info1.getGroupUuid().equals(info2.getGroupUuid())) {
480 // If both subscriptions are primary, show both.
481 if (!info1.isOpportunistic() && !info2.isOpportunistic()) return subscriptions;
482
483 // If carrier required, always show signal bar of primary subscription.
484 // Otherwise, show whichever subscription is currently active for Internet.
485 boolean alwaysShowPrimary = CarrierConfigManager.getDefaultConfig()
486 .getBoolean(CarrierConfigManager
487 .KEY_ALWAYS_SHOW_PRIMARY_SIGNAL_BAR_IN_OPPORTUNISTIC_NETWORK_BOOLEAN);
488 if (alwaysShowPrimary) {
489 subscriptions.remove(info1.isOpportunistic() ? info1 : info2);
490 } else {
491 subscriptions.remove(info1.getSubscriptionId() == mActiveMobileDataSubscription
492 ? info2 : info1);
493 }
494
495 }
496 }
497
498 return subscriptions;
Jim Miller52a61332014-11-12 19:29:51 -0800499 }
500
Adrian Roos7861c662014-07-25 15:37:28 +0200501 @Override
502 public void onTrustManagedChanged(boolean managed, int userId) {
Beverly1467c9e2020-02-18 13:31:29 -0500503 Assert.isMainThread();
Adrian Roos7861c662014-07-25 15:37:28 +0200504 mUserTrustIsManaged.put(userId, managed);
Lucas Dupinf2c53502019-10-03 13:56:18 -0700505 mUserTrustIsUsuallyManaged.put(userId, mTrustManager.isTrustUsuallyManaged(userId));
Adrian Roos7861c662014-07-25 15:37:28 +0200506 for (int i = 0; i < mCallbacks.size(); i++) {
507 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
508 if (cb != null) {
509 cb.onTrustManagedChanged(userId);
510 }
511 }
512 }
513
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700514 /**
Kevin Chyn8ae64b52020-04-06 15:48:49 -0700515 * Updates KeyguardUpdateMonitor's internal state to know if credential was attempted on
516 * bouncer. Note that this does not care if the credential was correct/incorrect. This is
517 * cleared when the user leaves the bouncer (unlocked, screen off, back to lockscreen, etc)
518 */
519 public void setCredentialAttempted() {
520 mCredentialAttempted = true;
521 updateBiometricListeningState();
522 }
523
524 /**
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700525 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is goingAway
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700526 */
527 public void setKeyguardGoingAway(boolean goingAway) {
528 mKeyguardGoingAway = goingAway;
Kevin Chyn8ae64b52020-04-06 15:48:49 -0700529 updateBiometricListeningState();
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700530 }
531
Kevin Chyn2fefd462017-04-28 12:18:19 -0700532 /**
533 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is occluded
Kevin Chyn2fefd462017-04-28 12:18:19 -0700534 */
535 public void setKeyguardOccluded(boolean occluded) {
536 mKeyguardOccluded = occluded;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200537 updateBiometricListeningState();
Kevin Chyn2fefd462017-04-28 12:18:19 -0700538 }
539
Kevin Chyn36778ff2017-09-07 19:55:38 -0700540 /**
Kevin Chyn6951d3d2019-06-10 14:07:13 -0700541 * Invoked when the secure camera is launched.
542 */
543 public void onCameraLaunched() {
544 mSecureCameraLaunched = true;
545 updateBiometricListeningState();
546 }
547
548 /**
Kevin Chyn36778ff2017-09-07 19:55:38 -0700549 * @return a cached version of DreamManager.isDreaming()
550 */
551 public boolean isDreaming() {
552 return mIsDreaming;
553 }
554
555 /**
556 * If the device is dreaming, awakens the device
557 */
558 public void awakenFromDream() {
559 if (mIsDreaming && mDreamManager != null) {
560 try {
561 mDreamManager.awaken();
562 } catch (RemoteException e) {
563 Log.e(TAG, "Unable to awaken from dream");
564 }
565 }
566 }
567
Lucas Dupin3d053532019-01-29 12:35:22 -0800568 @VisibleForTesting
Haining Chenc06c4812020-01-13 20:38:53 -0800569 protected void onFingerprintAuthenticated(int userId, boolean isStrongBiometric) {
Beverly1467c9e2020-02-18 13:31:29 -0500570 Assert.isMainThread();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700571 Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
Haining Chenc06c4812020-01-13 20:38:53 -0800572 mUserFingerprintAuthenticated.put(userId,
573 new BiometricAuthenticated(true, isStrongBiometric));
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700574 // Update/refresh trust state only if user can skip bouncer
575 if (getUserCanSkipBouncer(userId)) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200576 mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FINGERPRINT);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700577 }
Kevin Chyn625a0142017-04-10 14:53:59 -0700578 // Don't send cancel if authentication succeeds
579 mFingerprintCancelSignal = null;
Jim Millerf41fc962014-06-18 16:33:51 -0700580 for (int i = 0; i < mCallbacks.size(); i++) {
581 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
582 if (cb != null) {
Haining Chenc06c4812020-01-13 20:38:53 -0800583 cb.onBiometricAuthenticated(userId, BiometricSourceType.FINGERPRINT,
584 isStrongBiometric);
Jim Millerf41fc962014-06-18 16:33:51 -0700585 }
586 }
Kevin Chyn2fefd462017-04-28 12:18:19 -0700587
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200588 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE),
589 BIOMETRIC_CONTINUE_DELAY_MS);
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700590
Kevin Chyn2fefd462017-04-28 12:18:19 -0700591 // Only authenticate fingerprint once when assistant is visible
592 mAssistantVisible = false;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700593
Haining Chenc06c4812020-01-13 20:38:53 -0800594 // Report unlock with strong or non-strong biometric
595 reportSuccessfulBiometricUnlock(isStrongBiometric, userId);
596
Nick Desaulniers1d396752016-07-25 15:05:33 -0700597 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700598 }
599
Haining Chenc06c4812020-01-13 20:38:53 -0800600 private void reportSuccessfulBiometricUnlock(boolean isStrongBiometric, int userId) {
601 mBackgroundExecutor.execute(new Runnable() {
602 @Override
603 public void run() {
604 mLockPatternUtils.reportSuccessfulBiometricUnlock(isStrongBiometric, userId);
605 }
606 });
607 }
608
Jim Millerce7eb6d2015-04-03 19:29:13 -0700609 private void handleFingerprintAuthFailed() {
Beverly1467c9e2020-02-18 13:31:29 -0500610 Assert.isMainThread();
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700611 for (int i = 0; i < mCallbacks.size(); i++) {
612 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
613 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200614 cb.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700615 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700616 }
Lucas Dupin51996bb2019-05-16 17:56:43 -0700617 handleFingerprintHelp(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
618 mContext.getString(R.string.kg_fingerprint_not_recognized));
Jim Millerce7eb6d2015-04-03 19:29:13 -0700619 }
Jim Millerf41fc962014-06-18 16:33:51 -0700620
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700621 private void handleFingerprintAcquired(int acquireInfo) {
Beverly1467c9e2020-02-18 13:31:29 -0500622 Assert.isMainThread();
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700623 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
624 return;
625 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700626 for (int i = 0; i < mCallbacks.size(); i++) {
627 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
628 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200629 cb.onBiometricAcquired(BiometricSourceType.FINGERPRINT);
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700630 }
631 }
632 }
633
Haining Chenc06c4812020-01-13 20:38:53 -0800634 private void handleFingerprintAuthenticated(int authUserId, boolean isStrongBiometric) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700635 Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
Jim Millerf41fc962014-06-18 16:33:51 -0700636 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700637 final int userId;
638 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800639 userId = ActivityManager.getService().getCurrentUser().id;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700640 } catch (RemoteException e) {
641 Log.e(TAG, "Failed to get current user id: ", e);
642 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700643 }
Jim Miller837fa7e2016-08-08 20:16:22 -0700644 if (userId != authUserId) {
645 Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId);
646 return;
647 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700648 if (isFingerprintDisabled(userId)) {
649 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
650 return;
651 }
Haining Chenc06c4812020-01-13 20:38:53 -0800652 onFingerprintAuthenticated(userId, isStrongBiometric);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700653 } finally {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200654 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Jim Millerf41fc962014-06-18 16:33:51 -0700655 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700656 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700657 }
658
Jim Miller9f0753f2015-03-23 23:59:22 -0700659 private void handleFingerprintHelp(int msgId, String helpString) {
Beverly1467c9e2020-02-18 13:31:29 -0500660 Assert.isMainThread();
Jim Millerf41fc962014-06-18 16:33:51 -0700661 for (int i = 0; i < mCallbacks.size(); i++) {
662 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
663 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200664 cb.onBiometricHelp(msgId, helpString, BiometricSourceType.FINGERPRINT);
Jim Miller9f0753f2015-03-23 23:59:22 -0700665 }
666 }
667 }
668
Kevin Chyn0c45b072017-04-24 16:27:11 -0700669 private Runnable mRetryFingerprintAuthentication = new Runnable() {
670 @Override
671 public void run() {
672 Log.w(TAG, "Retrying fingerprint after HW unavailable, attempt " +
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200673 mHardwareFingerprintUnavailableRetryCount);
Kevin Chyn0c45b072017-04-24 16:27:11 -0700674 updateFingerprintListeningState();
675 }
676 };
677
Jim Miller9f0753f2015-03-23 23:59:22 -0700678 private void handleFingerprintError(int msgId, String errString) {
Beverly1467c9e2020-02-18 13:31:29 -0500679 Assert.isMainThread();
joshmccloskey7dee4542019-07-31 18:35:33 -0700680 if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED && mHandler.hasCallbacks(
681 mCancelNotReceived)) {
682 mHandler.removeCallbacks(mCancelNotReceived);
683 }
684
Jorim Jaggi86bed402015-08-20 18:20:02 -0700685 if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200686 && mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
687 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Kevin Chyn1123ba72018-10-26 10:34:06 -0700688 updateFingerprintListeningState();
Jorim Jaggi86bed402015-08-20 18:20:02 -0700689 } else {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200690 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Kevin Chyn8ae64b52020-04-06 15:48:49 -0700691 mFingerprintCancelSignal = null;
692 mFaceCancelSignal = null;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700693 }
Kevin Chyn0c45b072017-04-24 16:27:11 -0700694
695 if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) {
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700696 if (mHardwareFingerprintUnavailableRetryCount < HAL_ERROR_RETRY_MAX) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200697 mHardwareFingerprintUnavailableRetryCount++;
Kevin Chyn0c45b072017-04-24 16:27:11 -0700698 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700699 mHandler.postDelayed(mRetryFingerprintAuthentication, HAL_ERROR_RETRY_TIMEOUT);
Kevin Chyn0c45b072017-04-24 16:27:11 -0700700 }
701 }
702
Kevin Chyndf9d33e2017-05-03 21:40:12 -0700703 if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
Lucas Dupin8eec2682019-07-01 16:41:17 -0700704 mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
Kevin Chyndf9d33e2017-05-03 21:40:12 -0700705 getCurrentUser());
706 }
707
Kevin Chyn8ae64b52020-04-06 15:48:49 -0700708 if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT
709 || msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
710 mFingerprintLockedOut = true;
711 }
712
Jim Miller9f0753f2015-03-23 23:59:22 -0700713 for (int i = 0; i < mCallbacks.size(); i++) {
714 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
715 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200716 cb.onBiometricError(msgId, errString, BiometricSourceType.FINGERPRINT);
Jim Millerf41fc962014-06-18 16:33:51 -0700717 }
718 }
719 }
720
Jorim Jaggi3a464782015-08-28 16:59:13 -0700721 private void handleFingerprintLockoutReset() {
Kevin Chyn8ae64b52020-04-06 15:48:49 -0700722 mFingerprintLockedOut = false;
Jorim Jaggi3a464782015-08-28 16:59:13 -0700723 updateFingerprintListeningState();
724 }
725
Jorim Jaggi86bed402015-08-20 18:20:02 -0700726 private void setFingerprintRunningState(int fingerprintRunningState) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200727 boolean wasRunning = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
728 boolean isRunning = fingerprintRunningState == BIOMETRIC_STATE_RUNNING;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700729 mFingerprintRunningState = fingerprintRunningState;
Kevin Chynb4514d22019-04-15 13:47:25 -0700730 Log.d(TAG, "fingerprintRunningState: " + mFingerprintRunningState);
Jorim Jaggi86bed402015-08-20 18:20:02 -0700731 // Clients of KeyguardUpdateMonitor don't care about the internal state about the
Kevin Chynb4514d22019-04-15 13:47:25 -0700732 // asynchronousness of the cancel cycle. So only notify them if the actually running state
Jorim Jaggi86bed402015-08-20 18:20:02 -0700733 // has changed.
734 if (wasRunning != isRunning) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700735 notifyFingerprintRunningStateChanged();
736 }
737 }
738
739 private void notifyFingerprintRunningStateChanged() {
Beverly1467c9e2020-02-18 13:31:29 -0500740 Assert.isMainThread();
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700741 for (int i = 0; i < mCallbacks.size(); i++) {
742 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
743 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200744 cb.onBiometricRunningStateChanged(isFingerprintDetectionRunning(),
745 BiometricSourceType.FINGERPRINT);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700746 }
747 }
748 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200749
Lucas Dupin3d053532019-01-29 12:35:22 -0800750 @VisibleForTesting
Haining Chenc06c4812020-01-13 20:38:53 -0800751 protected void onFaceAuthenticated(int userId, boolean isStrongBiometric) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200752 Trace.beginSection("KeyGuardUpdateMonitor#onFaceAuthenticated");
Beverly1467c9e2020-02-18 13:31:29 -0500753 Assert.isMainThread();
Haining Chenc06c4812020-01-13 20:38:53 -0800754 mUserFaceAuthenticated.put(userId,
755 new BiometricAuthenticated(true, isStrongBiometric));
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200756 // Update/refresh trust state only if user can skip bouncer
757 if (getUserCanSkipBouncer(userId)) {
758 mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FACE);
759 }
760 // Don't send cancel if authentication succeeds
761 mFaceCancelSignal = null;
762 for (int i = 0; i < mCallbacks.size(); i++) {
763 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
764 if (cb != null) {
765 cb.onBiometricAuthenticated(userId,
Haining Chenc06c4812020-01-13 20:38:53 -0800766 BiometricSourceType.FACE,
767 isStrongBiometric);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200768 }
769 }
770
771 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE),
772 BIOMETRIC_CONTINUE_DELAY_MS);
773
774 // Only authenticate face once when assistant is visible
775 mAssistantVisible = false;
776
Haining Chenc06c4812020-01-13 20:38:53 -0800777 // Report unlock with strong or non-strong biometric
778 reportSuccessfulBiometricUnlock(isStrongBiometric, userId);
779
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200780 Trace.endSection();
781 }
782
783 private void handleFaceAuthFailed() {
Beverly1467c9e2020-02-18 13:31:29 -0500784 Assert.isMainThread();
Lucas Dupin38314812019-02-15 14:10:55 -0800785 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200786 for (int i = 0; i < mCallbacks.size(); i++) {
787 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
788 if (cb != null) {
789 cb.onBiometricAuthFailed(BiometricSourceType.FACE);
790 }
791 }
Lucas Dupin51996bb2019-05-16 17:56:43 -0700792 handleFaceHelp(BIOMETRIC_HELP_FACE_NOT_RECOGNIZED,
793 mContext.getString(R.string.kg_face_not_recognized));
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200794 }
795
796 private void handleFaceAcquired(int acquireInfo) {
Beverly1467c9e2020-02-18 13:31:29 -0500797 Assert.isMainThread();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200798 if (acquireInfo != FaceManager.FACE_ACQUIRED_GOOD) {
799 return;
800 }
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700801 if (DEBUG_FACE) Log.d(TAG, "Face acquired");
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200802 for (int i = 0; i < mCallbacks.size(); i++) {
803 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
804 if (cb != null) {
805 cb.onBiometricAcquired(BiometricSourceType.FACE);
806 }
807 }
808 }
809
Haining Chenc06c4812020-01-13 20:38:53 -0800810 private void handleFaceAuthenticated(int authUserId, boolean isStrongBiometric) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200811 Trace.beginSection("KeyGuardUpdateMonitor#handlerFaceAuthenticated");
812 try {
Lucas Dupin9bae9c22019-06-04 16:37:40 -0700813 if (mGoingToSleep) {
814 Log.d(TAG, "Aborted successful auth because device is going to sleep.");
815 return;
816 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200817 final int userId;
818 try {
819 userId = ActivityManager.getService().getCurrentUser().id;
820 } catch (RemoteException e) {
821 Log.e(TAG, "Failed to get current user id: ", e);
822 return;
823 }
824 if (userId != authUserId) {
825 Log.d(TAG, "Face authenticated for wrong user: " + authUserId);
826 return;
827 }
828 if (isFaceDisabled(userId)) {
829 Log.d(TAG, "Face authentication disabled by DPM for userId: " + userId);
830 return;
831 }
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700832 if (DEBUG_FACE) Log.d(TAG, "Face auth succeeded for user " + userId);
Haining Chenc06c4812020-01-13 20:38:53 -0800833 onFaceAuthenticated(userId, isStrongBiometric);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200834 } finally {
835 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
836 }
837 Trace.endSection();
838 }
839
840 private void handleFaceHelp(int msgId, String helpString) {
Beverly1467c9e2020-02-18 13:31:29 -0500841 Assert.isMainThread();
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700842 if (DEBUG_FACE) Log.d(TAG, "Face help received: " + helpString);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200843 for (int i = 0; i < mCallbacks.size(); i++) {
844 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
845 if (cb != null) {
846 cb.onBiometricHelp(msgId, helpString, BiometricSourceType.FACE);
847 }
848 }
849 }
850
851 private Runnable mRetryFaceAuthentication = new Runnable() {
852 @Override
853 public void run() {
854 Log.w(TAG, "Retrying face after HW unavailable, attempt " +
855 mHardwareFaceUnavailableRetryCount);
856 updateFaceListeningState();
857 }
858 };
859
860 private void handleFaceError(int msgId, String errString) {
Beverly1467c9e2020-02-18 13:31:29 -0500861 Assert.isMainThread();
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700862 if (DEBUG_FACE) Log.d(TAG, "Face error received: " + errString);
joshmccloskey7dee4542019-07-31 18:35:33 -0700863 if (msgId == FaceManager.FACE_ERROR_CANCELED && mHandler.hasCallbacks(mCancelNotReceived)) {
864 mHandler.removeCallbacks(mCancelNotReceived);
865 }
866
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200867 if (msgId == FaceManager.FACE_ERROR_CANCELED
868 && mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
869 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
Kevin Chyn1123ba72018-10-26 10:34:06 -0700870 updateFaceListeningState();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200871 } else {
872 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
873 }
874
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700875 if (msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE
876 || msgId == FaceManager.FACE_ERROR_UNABLE_TO_PROCESS) {
877 if (mHardwareFaceUnavailableRetryCount < HAL_ERROR_RETRY_MAX) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200878 mHardwareFaceUnavailableRetryCount++;
879 mHandler.removeCallbacks(mRetryFaceAuthentication);
Kevin Chyne1ac0c02019-07-26 17:54:46 -0700880 mHandler.postDelayed(mRetryFaceAuthentication, HAL_ERROR_RETRY_TIMEOUT);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200881 }
882 }
883
884 if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
Lucas Dupin8eec2682019-07-01 16:41:17 -0700885 mLockPatternUtils.requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200886 getCurrentUser());
887 }
888
889 for (int i = 0; i < mCallbacks.size(); i++) {
890 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
891 if (cb != null) {
892 cb.onBiometricError(msgId, errString,
893 BiometricSourceType.FACE);
894 }
895 }
896 }
897
898 private void handleFaceLockoutReset() {
899 updateFaceListeningState();
900 }
901
902 private void setFaceRunningState(int faceRunningState) {
903 boolean wasRunning = mFaceRunningState == BIOMETRIC_STATE_RUNNING;
904 boolean isRunning = faceRunningState == BIOMETRIC_STATE_RUNNING;
905 mFaceRunningState = faceRunningState;
Kevin Chynb4514d22019-04-15 13:47:25 -0700906 Log.d(TAG, "faceRunningState: " + mFaceRunningState);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200907 // Clients of KeyguardUpdateMonitor don't care about the internal state or about the
Kevin Chynb4514d22019-04-15 13:47:25 -0700908 // asynchronousness of the cancel cycle. So only notify them if the actually running state
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200909 // has changed.
910 if (wasRunning != isRunning) {
911 notifyFaceRunningStateChanged();
912 }
913 }
914
915 private void notifyFaceRunningStateChanged() {
Beverly1467c9e2020-02-18 13:31:29 -0500916 Assert.isMainThread();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200917 for (int i = 0; i < mCallbacks.size(); i++) {
918 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
919 if (cb != null) {
920 cb.onBiometricRunningStateChanged(isFaceDetectionRunning(),
921 BiometricSourceType.FACE);
922 }
923 }
924 }
925
Adrian Roos4a410172014-08-20 17:41:44 +0200926 private void handleFaceUnlockStateChanged(boolean running, int userId) {
Beverly1467c9e2020-02-18 13:31:29 -0500927 Assert.isMainThread();
Adrian Roos4a410172014-08-20 17:41:44 +0200928 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200929 for (int i = 0; i < mCallbacks.size(); i++) {
930 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
931 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200932 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200933 }
934 }
935 }
936
Adrian Roos4a410172014-08-20 17:41:44 +0200937 public boolean isFaceUnlockRunning(int userId) {
938 return mUserFaceUnlockRunning.get(userId);
939 }
940
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700941 public boolean isFingerprintDetectionRunning() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200942 return mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
943 }
944
945 public boolean isFaceDetectionRunning() {
946 return mFaceRunningState == BIOMETRIC_STATE_RUNNING;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700947 }
948
Jim Miller50e62182014-04-23 17:25:00 -0700949 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100950 // Don't allow trust agent if device is secured with a SIM PIN. This is here
951 // mainly because there's no other way to prompt the user to enter their SIM PIN
952 // once they get past the keyguard screen.
953 final boolean disabledBySimPin = isSimPinSecure();
954 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700955 }
956
Jim Miller06e34502014-07-17 14:46:05 -0700957 private boolean isFingerprintDisabled(int userId) {
958 final DevicePolicyManager dpm =
959 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
960 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
Dave Mankoff4b0ab652019-08-07 09:49:20 -0400961 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0
Adrian Roos733b6632015-08-21 14:32:35 -0700962 || isSimPinSecure();
Jim Miller06e34502014-07-17 14:46:05 -0700963 }
964
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200965 private boolean isFaceDisabled(int userId) {
966 final DevicePolicyManager dpm =
967 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
Lucas Dupin8968f6a2019-08-09 17:41:15 -0700968 // TODO(b/140035044)
969 return whitelistIpcs(() -> dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200970 & DevicePolicyManager.KEYGUARD_DISABLE_FACE) != 0
Lucas Dupin8968f6a2019-08-09 17:41:15 -0700971 || isSimPinSecure());
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200972 }
973
974
Selim Cineke8bae622015-07-15 13:24:06 -0700975 public boolean getUserCanSkipBouncer(int userId) {
Steven Wucfe398d2019-03-21 11:32:15 -0400976 return getUserHasTrust(userId) || getUserUnlockedWithBiometric(userId);
Selim Cineke8bae622015-07-15 13:24:06 -0700977 }
978
Adrian Roos46842d92014-03-27 14:58:03 +0100979 public boolean getUserHasTrust(int userId) {
Selim Cineke8bae622015-07-15 13:24:06 -0700980 return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100981 }
982
Steven Wucfe398d2019-03-21 11:32:15 -0400983 /**
984 * Returns whether the user is unlocked with biometrics.
985 */
986 public boolean getUserUnlockedWithBiometric(int userId) {
Haining Chenc06c4812020-01-13 20:38:53 -0800987 BiometricAuthenticated fingerprint = mUserFingerprintAuthenticated.get(userId);
988 BiometricAuthenticated face = mUserFaceAuthenticated.get(userId);
989 boolean fingerprintAllowed = fingerprint != null && fingerprint.mAuthenticated
990 && isUnlockingWithBiometricAllowed(fingerprint.mIsStrongBiometric);
991 boolean faceAllowed = face != null && face.mAuthenticated
992 && isUnlockingWithBiometricAllowed(face.mIsStrongBiometric);
993 return fingerprintAllowed || faceAllowed;
Steven Wucfe398d2019-03-21 11:32:15 -0400994 }
995
Adrian Roos7861c662014-07-25 15:37:28 +0200996 public boolean getUserTrustIsManaged(int userId) {
997 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
998 }
999
Yvonne Jiangb7024a22019-12-05 16:57:08 -08001000 private void updateSecondaryLockscreenRequirement(int userId) {
1001 Intent oldIntent = mSecondaryLockscreenRequirement.get(userId);
Yvonne Jiang8345da32020-03-19 15:01:16 -07001002 boolean enabled = mDevicePolicyManager.isSecondaryLockscreenEnabled(UserHandle.of(userId));
Yvonne Jiangb7024a22019-12-05 16:57:08 -08001003 boolean changed = false;
1004
1005 if (enabled && (oldIntent == null)) {
Yvonne Jiang70a62372020-03-31 16:51:17 -07001006 ComponentName supervisorComponent =
1007 mDevicePolicyManager.getProfileOwnerOrDeviceOwnerSupervisionComponent(
1008 UserHandle.of(userId));
1009 if (supervisorComponent == null) {
1010 Log.e(TAG, "No Profile Owner or Device Owner supervision app found for User "
1011 + userId);
Yuhan Zhao4b767ff2020-03-23 11:59:18 -07001012 } else {
1013 Intent intent =
1014 new Intent(DevicePolicyManager.ACTION_BIND_SECONDARY_LOCKSCREEN_SERVICE)
Yvonne Jiang70a62372020-03-31 16:51:17 -07001015 .setPackage(supervisorComponent.getPackageName());
Yuhan Zhao4b767ff2020-03-23 11:59:18 -07001016 ResolveInfo resolveInfo = mContext.getPackageManager().resolveService(intent, 0);
1017 if (resolveInfo != null && resolveInfo.serviceInfo != null) {
1018 Intent launchIntent =
1019 new Intent().setComponent(resolveInfo.serviceInfo.getComponentName());
1020 mSecondaryLockscreenRequirement.put(userId, launchIntent);
1021 changed = true;
1022 }
Yvonne Jiangb7024a22019-12-05 16:57:08 -08001023 }
1024 } else if (!enabled && (oldIntent != null)) {
1025 mSecondaryLockscreenRequirement.put(userId, null);
1026 changed = true;
1027 }
1028 if (changed) {
1029 for (int i = 0; i < mCallbacks.size(); i++) {
1030 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1031 if (cb != null) {
1032 cb.onSecondaryLockscreenRequirementChanged(userId);
1033 }
1034 }
1035 }
1036 }
1037
1038 /**
1039 * Returns an Intent by which to bind to a service that will provide additional security screen
1040 * content that must be shown prior to dismissing the keyguard for this user.
1041 */
1042 public Intent getSecondaryLockscreenRequirement(int userId) {
1043 return mSecondaryLockscreenRequirement.get(userId);
1044 }
1045
Lucas Dupinf2c53502019-10-03 13:56:18 -07001046 /**
1047 * Cached version of {@link TrustManager#isTrustUsuallyManaged(int)}.
1048 */
1049 public boolean isTrustUsuallyManaged(int userId) {
Beverly1467c9e2020-02-18 13:31:29 -05001050 Assert.isMainThread();
Lucas Dupinf2c53502019-10-03 13:56:18 -07001051 return mUserTrustIsUsuallyManaged.get(userId);
1052 }
1053
Haining Chenc06c4812020-01-13 20:38:53 -08001054 public boolean isUnlockingWithBiometricAllowed(boolean isStrongBiometric) {
1055 return mStrongAuthTracker.isUnlockingWithBiometricAllowed(isStrongBiometric);
Adrian Roosb5e47222015-08-14 15:53:06 -07001056 }
1057
Lucas Dupin16013822018-05-17 18:00:16 -07001058 public boolean isUserInLockdown(int userId) {
Lucas Dupin8eec2682019-07-01 16:41:17 -07001059 return containsFlag(mStrongAuthTracker.getStrongAuthForUser(userId),
1060 STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
Lucas Dupin16013822018-05-17 18:00:16 -07001061 }
1062
Lucas Dupin7825b942019-06-03 20:22:39 -07001063 public boolean userNeedsStrongAuth() {
1064 return mStrongAuthTracker.getStrongAuthForUser(getCurrentUser())
1065 != LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
1066 }
1067
Lucas Dupin8eec2682019-07-01 16:41:17 -07001068 private boolean containsFlag(int haystack, int needle) {
1069 return (haystack & needle) != 0;
1070 }
1071
Jorim Jaggi031f7952016-09-01 16:39:26 -07001072 public boolean needsSlowUnlockTransition() {
1073 return mNeedsSlowUnlockTransition;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001074 }
1075
Adrian Roosb5e47222015-08-14 15:53:06 -07001076 public StrongAuthTracker getStrongAuthTracker() {
1077 return mStrongAuthTracker;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001078 }
1079
Adrian Roos1de8bcb2015-08-19 16:52:52 -07001080 private void notifyStrongAuthStateChanged(int userId) {
Beverly1467c9e2020-02-18 13:31:29 -05001081 Assert.isMainThread();
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001082 for (int i = 0; i < mCallbacks.size(); i++) {
1083 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1084 if (cb != null) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -07001085 cb.onStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001086 }
1087 }
Selim Cinek1fcafc42015-07-20 14:39:25 -07001088 }
1089
Adrian Roos91ba3072017-02-14 16:50:46 +01001090 public boolean isScreenOn() {
1091 return mScreenOn;
1092 }
1093
Lucas Dupinef886542018-01-03 16:03:07 -08001094 private void dispatchErrorMessage(CharSequence message) {
Beverly1467c9e2020-02-18 13:31:29 -05001095 Assert.isMainThread();
Lucas Dupinef886542018-01-03 16:03:07 -08001096 for (int i = 0; i < mCallbacks.size(); i++) {
1097 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1098 if (cb != null) {
1099 cb.onTrustAgentErrorMessage(message);
1100 }
1101 }
1102 }
1103
Lucas Dupin3d053532019-01-29 12:35:22 -08001104 @VisibleForTesting
1105 void setAssistantVisible(boolean assistantVisible) {
1106 mAssistantVisible = assistantVisible;
1107 updateBiometricListeningState();
1108 }
1109
Jim Miller8f09fd22013-03-14 19:04:28 -07001110 static class DisplayClientState {
1111 public int clientGeneration;
1112 public boolean clearing;
1113 public PendingIntent intent;
1114 public int playbackState;
1115 public long playbackEventTime;
1116 }
1117
1118 private DisplayClientState mDisplayClientState = new DisplayClientState();
1119
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001120 @VisibleForTesting
Lucas Dupin7ff82b02018-05-16 12:14:10 -07001121 protected final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001122
Jim Millerd72d5ac2015-09-29 18:55:32 -07001123 @Override
Jim Millerbbf1a742012-07-17 18:30:30 -07001124 public void onReceive(Context context, Intent intent) {
1125 final String action = intent.getAction();
1126 if (DEBUG) Log.d(TAG, "received broadcast " + action);
1127
1128 if (Intent.ACTION_TIME_TICK.equals(action)
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05001129 || Intent.ACTION_TIME_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -07001130 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05001131 } else if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
1132 final Message msg = mHandler.obtainMessage(
Suprabh Shukla2e7408e2020-03-10 17:09:25 -07001133 MSG_TIMEZONE_UPDATE, intent.getStringExtra(Intent.EXTRA_TIMEZONE));
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05001134 mHandler.sendMessage(msg);
Jim Millerbbf1a742012-07-17 18:30:30 -07001135 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
Adrian Roos0c859ae2015-11-23 16:47:50 -08001136
Jim Millerbbf1a742012-07-17 18:30:30 -07001137 final Message msg = mHandler.obtainMessage(
Raff Tsaif4ea5622019-06-26 16:15:21 +08001138 MSG_BATTERY_UPDATE, new BatteryStatus(intent));
Jim Millerbbf1a742012-07-17 18:30:30 -07001139 mHandler.sendMessage(msg);
Daniel Bright350f7f92020-01-22 14:24:11 -08001140 } else if (Intent.ACTION_SIM_STATE_CHANGED.equals(action)) {
Bill Linef81cbd2018-07-05 17:48:49 +08001141 SimData args = SimData.fromIntent(intent);
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001142 // ACTION_SIM_STATE_CHANGED is rebroadcast after unlocking the device to
1143 // keep compatibility with apps that aren't direct boot aware.
1144 // SysUI should just ignore this broadcast because it was already received
1145 // and processed previously.
Meng Wang0e8d91a2020-01-17 14:58:01 -08001146 if (intent.getBooleanExtra(Intent.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
Bill Linef81cbd2018-07-05 17:48:49 +08001147 // Guarantee mTelephonyCapable state after SysUI crash and restart
Jayachandran Cf5436a62019-11-08 18:22:45 -08001148 if (args.simState == TelephonyManager.SIM_STATE_ABSENT) {
Bill Linef81cbd2018-07-05 17:48:49 +08001149 mHandler.obtainMessage(MSG_TELEPHONY_CAPABLE, true).sendToTarget();
1150 }
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001151 return;
1152 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001153 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -08001154 Log.v(TAG, "action " + action
Dave Mankoff4b0ab652019-08-07 09:49:20 -04001155 + " state: " + intent.getStringExtra(
Jayachandran C0173df82019-12-19 12:11:03 -08001156 Intent.EXTRA_SIM_STATE)
Dave Mankoff4b0ab652019-08-07 09:49:20 -04001157 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -07001158 }
Jim Miller52a61332014-11-12 19:29:51 -08001159 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
1160 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -07001161 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
1162 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
1163 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Jason Monk052082c2015-06-11 11:35:23 -04001164 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
1165 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Jayachandran C041e7692019-12-20 16:20:02 -08001166 } else if (Intent.ACTION_SERVICE_STATE.equals(action)) {
Etan Cohen47051d82015-07-06 16:19:04 -07001167 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
Daniel Bright63514be2020-01-15 12:10:53 -08001168 int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
Etan Cohen47051d82015-07-06 16:19:04 -07001169 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
1170 if (DEBUG) {
1171 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
1172 + subId);
1173 }
Bonian Chena7e9e8c2019-06-02 23:59:31 +00001174 mHandler.sendMessage(
1175 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
Daniel Bright350f7f92020-01-22 14:24:11 -08001176 } else if (TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED.equals(action)) {
Fabian Kozynskiccde55d2019-06-26 10:06:09 -04001177 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
Alex Chauff7653d2018-02-01 17:18:08 +00001178 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
1179 action)) {
1180 mHandler.sendEmptyMessage(MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001181 }
1182 }
1183 };
Jim Miller2de5ee82012-06-14 22:22:50 -07001184
Lucas Dupin3d053532019-01-29 12:35:22 -08001185 @VisibleForTesting
1186 protected final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001187
Jim Millerd72d5ac2015-09-29 18:55:32 -07001188 @Override
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001189 public void onReceive(Context context, Intent intent) {
1190 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +02001191 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
1192 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
1193 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001194 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
1195 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +02001196 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
Dave Mankoff4b0ab652019-08-07 09:49:20 -04001197 Trace.beginSection(
1198 "KeyguardUpdateMonitor.mBroadcastAllReceiver#onReceive "
1199 + "ACTION_FACE_UNLOCK_STARTED");
Adrian Roos48c796c2014-09-01 14:59:23 +02001200 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
1201 getSendingUserId()));
Nick Desaulniers1d396752016-07-25 15:05:33 -07001202 Trace.endSection();
Adrian Roos48c796c2014-09-01 14:59:23 +02001203 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
1204 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
1205 getSendingUserId()));
1206 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
1207 .equals(action)) {
Yvonne Jiangb7024a22019-12-05 16:57:08 -08001208 mHandler.sendMessage(mHandler.obtainMessage(MSG_DPM_STATE_CHANGED,
1209 getSendingUserId()));
Jorim Jaggidadafd42016-09-30 07:20:25 -07001210 } else if (ACTION_USER_UNLOCKED.equals(action)) {
Lucas Dupin6c6d5732019-08-27 17:36:05 -07001211 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_UNLOCKED,
1212 getSendingUserId(), 0));
1213 } else if (ACTION_USER_STOPPED.equals(action)) {
1214 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_STOPPED,
1215 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1), 0));
1216 } else if (ACTION_USER_REMOVED.equals(action)) {
1217 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_REMOVED,
1218 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, -1), 0));
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001219 }
1220 }
1221 };
Jim Miller9f0753f2015-03-23 23:59:22 -07001222
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001223 private final FingerprintManager.LockoutResetCallback mFingerprintLockoutResetCallback
Jorim Jaggi3a464782015-08-28 16:59:13 -07001224 = new FingerprintManager.LockoutResetCallback() {
1225 @Override
1226 public void onLockoutReset() {
1227 handleFingerprintLockoutReset();
1228 }
1229 };
1230
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001231 private final FaceManager.LockoutResetCallback mFaceLockoutResetCallback
1232 = new FaceManager.LockoutResetCallback() {
1233 @Override
1234 public void onLockoutReset() {
1235 handleFaceLockoutReset();
1236 }
1237 };
1238
1239 private FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback
Jim Miller9f0753f2015-03-23 23:59:22 -07001240 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -07001241
1242 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -07001243 public void onAuthenticationFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001244 handleFingerprintAuthFailed();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001245 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001246
1247 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -07001248 public void onAuthenticationSucceeded(AuthenticationResult result) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001249 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
Haining Chenc06c4812020-01-13 20:38:53 -08001250 handleFingerprintAuthenticated(result.getUserId(), result.isStrongBiometric());
Nick Desaulniers1d396752016-07-25 15:05:33 -07001251 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -07001252 }
1253
1254 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -07001255 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001256 handleFingerprintHelp(helpMsgId, helpString.toString());
Jim Miller9f0753f2015-03-23 23:59:22 -07001257 }
1258
1259 @Override
1260 public void onAuthenticationError(int errMsgId, CharSequence errString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001261 handleFingerprintError(errMsgId, errString.toString());
1262 }
1263
1264 @Override
1265 public void onAuthenticationAcquired(int acquireInfo) {
1266 handleFingerprintAcquired(acquireInfo);
Jim Millerf41fc962014-06-18 16:33:51 -07001267 }
1268 };
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001269
Lucas Dupin3d053532019-01-29 12:35:22 -08001270 @VisibleForTesting
1271 FaceManager.AuthenticationCallback mFaceAuthenticationCallback
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001272 = new FaceManager.AuthenticationCallback() {
1273
1274 @Override
1275 public void onAuthenticationFailed() {
1276 handleFaceAuthFailed();
1277 }
1278
1279 @Override
1280 public void onAuthenticationSucceeded(FaceManager.AuthenticationResult result) {
1281 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
Haining Chenc06c4812020-01-13 20:38:53 -08001282 handleFaceAuthenticated(result.getUserId(), result.isStrongBiometric());
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001283 Trace.endSection();
1284 }
1285
1286 @Override
1287 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
1288 handleFaceHelp(helpMsgId, helpString.toString());
1289 }
1290
1291 @Override
1292 public void onAuthenticationError(int errMsgId, CharSequence errString) {
1293 handleFaceError(errMsgId, errString.toString());
1294 }
1295
1296 @Override
1297 public void onAuthenticationAcquired(int acquireInfo) {
1298 handleFaceAcquired(acquireInfo);
1299 }
1300 };
1301
Jim Miller9f0753f2015-03-23 23:59:22 -07001302 private CancellationSignal mFingerprintCancelSignal;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001303 private CancellationSignal mFaceCancelSignal;
Jim Miller9f0753f2015-03-23 23:59:22 -07001304 private FingerprintManager mFpm;
Kevin Chynb7b54a62018-09-28 18:48:12 -07001305 private FaceManager mFaceManager;
Kevin Chyn8ae64b52020-04-06 15:48:49 -07001306 private boolean mFingerprintLockedOut;
Fabian Kozynskib00c70b2020-04-03 12:41:31 -04001307 private TelephonyManager mTelephonyManager;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001308
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001309 /**
Jim Miller47088bb2009-11-24 00:40:16 -08001310 * When we receive a
1311 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -07001312 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001313 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -08001314 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001315 */
Jim Miller52a61332014-11-12 19:29:51 -08001316 private static class SimData {
Jayachandran Cf5436a62019-11-08 18:22:45 -08001317 public int simState;
Jim Miller52a61332014-11-12 19:29:51 -08001318 public int slotId;
1319 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001320
Jayachandran Cf5436a62019-11-08 18:22:45 -08001321 SimData(int state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -08001322 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -08001323 slotId = slot;
1324 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -08001325 }
1326
Jim Miller52a61332014-11-12 19:29:51 -08001327 static SimData fromIntent(Intent intent) {
Jayachandran Cf5436a62019-11-08 18:22:45 -08001328 int state;
Daniel Bright350f7f92020-01-22 14:24:11 -08001329 if (!Intent.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001330 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
1331 }
Jayachandran C0173df82019-12-19 12:11:03 -08001332 String stateExtra = intent.getStringExtra(Intent.EXTRA_SIM_STATE);
Daniel Bright63514be2020-01-15 12:10:53 -08001333 int slotId = intent.getIntExtra(SubscriptionManager.EXTRA_SLOT_INDEX, 0);
1334 int subId = intent.getIntExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX,
Wink Savilled09c4ca2014-11-22 10:08:16 -08001335 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Jayachandran C0173df82019-12-19 12:11:03 -08001336 if (Intent.SIM_STATE_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -07001337 final String absentReason = intent
Jayachandran C0173df82019-12-19 12:11:03 -08001338 .getStringExtra(Intent.EXTRA_SIM_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -07001339
Jayachandran C0173df82019-12-19 12:11:03 -08001340 if (Intent.SIM_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -07001341 absentReason)) {
Jayachandran Cf5436a62019-11-08 18:22:45 -08001342 state = TelephonyManager.SIM_STATE_PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -07001343 } else {
Jayachandran Cf5436a62019-11-08 18:22:45 -08001344 state = TelephonyManager.SIM_STATE_ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -07001345 }
Jayachandran C0173df82019-12-19 12:11:03 -08001346 } else if (Intent.SIM_STATE_READY.equals(stateExtra)) {
Jayachandran Cf5436a62019-11-08 18:22:45 -08001347 state = TelephonyManager.SIM_STATE_READY;
Jayachandran C0173df82019-12-19 12:11:03 -08001348 } else if (Intent.SIM_STATE_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001349 final String lockedReason = intent
Jayachandran C0173df82019-12-19 12:11:03 -08001350 .getStringExtra(Intent.EXTRA_SIM_LOCKED_REASON);
1351 if (Intent.SIM_LOCKED_ON_PIN.equals(lockedReason)) {
Jayachandran Cf5436a62019-11-08 18:22:45 -08001352 state = TelephonyManager.SIM_STATE_PIN_REQUIRED;
Jayachandran C0173df82019-12-19 12:11:03 -08001353 } else if (Intent.SIM_LOCKED_ON_PUK.equals(lockedReason)) {
Jayachandran Cf5436a62019-11-08 18:22:45 -08001354 state = TelephonyManager.SIM_STATE_PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001355 } else {
Jayachandran Cf5436a62019-11-08 18:22:45 -08001356 state = TelephonyManager.SIM_STATE_UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001357 }
Jayachandran C0173df82019-12-19 12:11:03 -08001358 } else if (Intent.SIM_LOCKED_NETWORK.equals(stateExtra)) {
Jayachandran Cf5436a62019-11-08 18:22:45 -08001359 state = TelephonyManager.SIM_STATE_NETWORK_LOCKED;
Jayachandran C0173df82019-12-19 12:11:03 -08001360 } else if (Intent.SIM_STATE_CARD_IO_ERROR.equals(stateExtra)) {
Jayachandran Cf5436a62019-11-08 18:22:45 -08001361 state = TelephonyManager.SIM_STATE_CARD_IO_ERROR;
Jayachandran C0173df82019-12-19 12:11:03 -08001362 } else if (Intent.SIM_STATE_LOADED.equals(stateExtra)
1363 || Intent.SIM_STATE_IMSI.equals(stateExtra)) {
Jim Miller109f1fd2012-09-19 20:44:16 -07001364 // This is required because telephony doesn't return to "READY" after
1365 // these state transitions. See bug 7197471.
Jayachandran Cf5436a62019-11-08 18:22:45 -08001366 state = TelephonyManager.SIM_STATE_READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001367 } else {
Jayachandran Cf5436a62019-11-08 18:22:45 -08001368 state = TelephonyManager.SIM_STATE_UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001369 }
Jim Miller52a61332014-11-12 19:29:51 -08001370 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001371 }
1372
Jim Millerd72d5ac2015-09-29 18:55:32 -07001373 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001374 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -08001375 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001376 }
1377 }
1378
Lucas Dupin3d053532019-01-29 12:35:22 -08001379 public static class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
1380 private final Consumer<Integer> mStrongAuthRequiredChangedCallback;
1381
1382 public StrongAuthTracker(Context context,
1383 Consumer<Integer> strongAuthRequiredChangedCallback) {
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001384 super(context);
Lucas Dupin3d053532019-01-29 12:35:22 -08001385 mStrongAuthRequiredChangedCallback = strongAuthRequiredChangedCallback;
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001386 }
Adrian Roosb5e47222015-08-14 15:53:06 -07001387
Haining Chenc06c4812020-01-13 20:38:53 -08001388 public boolean isUnlockingWithBiometricAllowed(boolean isStrongBiometric) {
Adrian Roosb5e47222015-08-14 15:53:06 -07001389 int userId = getCurrentUser();
Haining Chenc06c4812020-01-13 20:38:53 -08001390 return isBiometricAllowedForUser(isStrongBiometric, userId);
Adrian Roosb5e47222015-08-14 15:53:06 -07001391 }
1392
1393 public boolean hasUserAuthenticatedSinceBoot() {
1394 int userId = getCurrentUser();
1395 return (getStrongAuthForUser(userId)
1396 & STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
1397 }
1398
1399 @Override
1400 public void onStrongAuthRequiredChanged(int userId) {
Lucas Dupin3d053532019-01-29 12:35:22 -08001401 mStrongAuthRequiredChangedCallback.accept(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -07001402 }
1403 }
1404
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001405 protected void handleStartedWakingUp() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001406 Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
Beverly1467c9e2020-02-18 13:31:29 -05001407 Assert.isMainThread();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001408 updateBiometricListeningState();
Dave Mankoff4b0ab652019-08-07 09:49:20 -04001409 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Miller20daffd2013-10-07 14:59:53 -07001410 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1411 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001412 cb.onStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -07001413 }
1414 }
Nick Desaulniers1d396752016-07-25 15:05:33 -07001415 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -07001416 }
1417
Jorim Jaggi95e40382015-09-16 15:53:42 -07001418 protected void handleStartedGoingToSleep(int arg1) {
Beverly1467c9e2020-02-18 13:31:29 -05001419 Assert.isMainThread();
Curtis Belmonte6a0634d2019-08-19 13:13:01 -07001420 mLockIconPressed = false;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001421 clearBiometricRecognized();
Dave Mankoff4b0ab652019-08-07 09:49:20 -04001422 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Miller20daffd2013-10-07 14:59:53 -07001423 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1424 if (cb != null) {
Jorim Jaggi95e40382015-09-16 15:53:42 -07001425 cb.onStartedGoingToSleep(arg1);
1426 }
1427 }
1428 mGoingToSleep = true;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001429 updateBiometricListeningState();
Jorim Jaggi95e40382015-09-16 15:53:42 -07001430 }
1431
1432 protected void handleFinishedGoingToSleep(int arg1) {
Beverly1467c9e2020-02-18 13:31:29 -05001433 Assert.isMainThread();
Jorim Jaggi95e40382015-09-16 15:53:42 -07001434 mGoingToSleep = false;
Dave Mankoff4b0ab652019-08-07 09:49:20 -04001435 for (int i = 0; i < mCallbacks.size(); i++) {
Jorim Jaggi95e40382015-09-16 15:53:42 -07001436 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1437 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001438 cb.onFinishedGoingToSleep(arg1);
Jim Miller20daffd2013-10-07 14:59:53 -07001439 }
1440 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001441 updateBiometricListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001442 }
1443
Jorim Jaggif1518da2015-07-30 11:56:36 -07001444 private void handleScreenTurnedOn() {
Beverly1467c9e2020-02-18 13:31:29 -05001445 Assert.isMainThread();
Dave Mankoff4b0ab652019-08-07 09:49:20 -04001446 for (int i = 0; i < mCallbacks.size(); i++) {
Jorim Jaggif1518da2015-07-30 11:56:36 -07001447 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1448 if (cb != null) {
1449 cb.onScreenTurnedOn();
1450 }
1451 }
1452 }
1453
1454 private void handleScreenTurnedOff() {
Lucas Dupind236ee32019-10-08 15:33:59 -07001455 final String tag = "KeyguardUpdateMonitor#handleScreenTurnedOff";
1456 DejankUtils.startDetectingBlockingIpcs(tag);
Beverly1467c9e2020-02-18 13:31:29 -05001457 Assert.isMainThread();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001458 mHardwareFingerprintUnavailableRetryCount = 0;
1459 mHardwareFaceUnavailableRetryCount = 0;
Dave Mankoff4b0ab652019-08-07 09:49:20 -04001460 for (int i = 0; i < mCallbacks.size(); i++) {
Jorim Jaggif1518da2015-07-30 11:56:36 -07001461 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1462 if (cb != null) {
1463 cb.onScreenTurnedOff();
1464 }
1465 }
Lucas Dupind236ee32019-10-08 15:33:59 -07001466 DejankUtils.stopDetectingBlockingIpcs(tag);
Jorim Jaggif1518da2015-07-30 11:56:36 -07001467 }
1468
Selim Cinek99415392016-09-09 14:58:41 -07001469 private void handleDreamingStateChanged(int dreamStart) {
Beverly1467c9e2020-02-18 13:31:29 -05001470 Assert.isMainThread();
Kevin Chyn36778ff2017-09-07 19:55:38 -07001471 mIsDreaming = dreamStart == 1;
Dave Mankoff4b0ab652019-08-07 09:49:20 -04001472 for (int i = 0; i < mCallbacks.size(); i++) {
Selim Cinek99415392016-09-09 14:58:41 -07001473 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1474 if (cb != null) {
Kevin Chyn36778ff2017-09-07 19:55:38 -07001475 cb.onDreamingStateChanged(mIsDreaming);
Selim Cinek99415392016-09-09 14:58:41 -07001476 }
1477 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001478 updateBiometricListeningState();
Selim Cinek99415392016-09-09 14:58:41 -07001479 }
1480
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001481 private void handleUserInfoChanged(int userId) {
Beverly1467c9e2020-02-18 13:31:29 -05001482 Assert.isMainThread();
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001483 for (int i = 0; i < mCallbacks.size(); i++) {
1484 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1485 if (cb != null) {
1486 cb.onUserInfoChanged(userId);
1487 }
1488 }
1489 }
1490
Lucas Dupin6c6d5732019-08-27 17:36:05 -07001491 private void handleUserUnlocked(int userId) {
Beverly1467c9e2020-02-18 13:31:29 -05001492 Assert.isMainThread();
Lucas Dupin6c6d5732019-08-27 17:36:05 -07001493 mUserIsUnlocked.put(userId, true);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001494 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1495 for (int i = 0; i < mCallbacks.size(); i++) {
1496 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1497 if (cb != null) {
1498 cb.onUserUnlocked();
1499 }
1500 }
1501 }
1502
Lucas Dupin6c6d5732019-08-27 17:36:05 -07001503 private void handleUserStopped(int userId) {
Beverly1467c9e2020-02-18 13:31:29 -05001504 Assert.isMainThread();
Lucas Dupin6c6d5732019-08-27 17:36:05 -07001505 mUserIsUnlocked.put(userId, mUserManager.isUserUnlocked(userId));
1506 }
1507
Lucas Dupinf2c53502019-10-03 13:56:18 -07001508 @VisibleForTesting
1509 void handleUserRemoved(int userId) {
Beverly1467c9e2020-02-18 13:31:29 -05001510 Assert.isMainThread();
Lucas Dupin6c6d5732019-08-27 17:36:05 -07001511 mUserIsUnlocked.delete(userId);
Lucas Dupinf2c53502019-10-03 13:56:18 -07001512 mUserTrustIsUsuallyManaged.delete(userId);
Lucas Dupin6c6d5732019-08-27 17:36:05 -07001513 }
1514
Fabian Kozynskib6a20372020-04-01 09:36:43 -04001515 private void registerRingerTracker() {
1516 mRingerModeTracker.getRingerMode().observeForever(mRingerModeObserver);
1517 }
1518
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001519 @VisibleForTesting
Dave Mankoffe2294692019-08-14 11:53:13 -04001520 @Inject
Beverly1467c9e2020-02-18 13:31:29 -05001521 protected KeyguardUpdateMonitor(
1522 Context context,
1523 @Main Looper mainLooper,
Fabian Kozynski5ca7a512019-10-16 19:56:11 +00001524 BroadcastDispatcher broadcastDispatcher,
Ned Burnsaaeb44b2020-02-12 23:48:26 -05001525 DumpManager dumpManager,
Fabian Kozynskib6a20372020-04-01 09:36:43 -04001526 RingerModeTracker ringerModeTracker,
Curtis Belmonte9dc68152020-05-08 17:12:13 -07001527 @Background Executor backgroundExecutor,
1528 StatusBarStateController statusBarStateController) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001529 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -08001530 mSubscriptionManager = SubscriptionManager.from(context);
Michael Jurkafff56142012-11-28 16:51:00 -08001531 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Lucas Dupin3d053532019-01-29 12:35:22 -08001532 mStrongAuthTracker = new StrongAuthTracker(context, this::notifyStrongAuthStateChanged);
Haining Chenc06c4812020-01-13 20:38:53 -08001533 mBackgroundExecutor = backgroundExecutor;
Beverly4e7dd9a2020-02-28 17:04:21 -05001534 mBroadcastDispatcher = broadcastDispatcher;
Fabian Kozynskib6a20372020-04-01 09:36:43 -04001535 mRingerModeTracker = ringerModeTracker;
Curtis Belmonte9dc68152020-05-08 17:12:13 -07001536 mStatusBarStateController = statusBarStateController;
Ned Burnsaaeb44b2020-02-12 23:48:26 -05001537 dumpManager.registerDumpable(getClass().getName(), this);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001538
Dave Mankoffe2294692019-08-14 11:53:13 -04001539 mHandler = new Handler(mainLooper) {
1540 @Override
1541 public void handleMessage(Message msg) {
1542 switch (msg.what) {
1543 case MSG_TIME_UPDATE:
1544 handleTimeUpdate();
1545 break;
1546 case MSG_TIMEZONE_UPDATE:
1547 handleTimeZoneUpdate((String) msg.obj);
1548 break;
1549 case MSG_BATTERY_UPDATE:
1550 handleBatteryUpdate((BatteryStatus) msg.obj);
1551 break;
1552 case MSG_SIM_STATE_CHANGE:
Jayachandran Cf5436a62019-11-08 18:22:45 -08001553 handleSimStateChange(msg.arg1, msg.arg2, (int) msg.obj);
Dave Mankoffe2294692019-08-14 11:53:13 -04001554 break;
1555 case MSG_RINGER_MODE_CHANGED:
1556 handleRingerModeChange(msg.arg1);
1557 break;
1558 case MSG_PHONE_STATE_CHANGED:
1559 handlePhoneStateChanged((String) msg.obj);
1560 break;
1561 case MSG_DEVICE_PROVISIONED:
1562 handleDeviceProvisioned();
1563 break;
1564 case MSG_DPM_STATE_CHANGED:
Yvonne Jiangb7024a22019-12-05 16:57:08 -08001565 handleDevicePolicyManagerStateChanged(msg.arg1);
Dave Mankoffe2294692019-08-14 11:53:13 -04001566 break;
1567 case MSG_USER_SWITCHING:
1568 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
1569 break;
1570 case MSG_USER_SWITCH_COMPLETE:
1571 handleUserSwitchComplete(msg.arg1);
1572 break;
1573 case MSG_KEYGUARD_RESET:
1574 handleKeyguardReset();
1575 break;
1576 case MSG_KEYGUARD_BOUNCER_CHANGED:
1577 handleKeyguardBouncerChanged(msg.arg1);
1578 break;
Dave Mankoffe2294692019-08-14 11:53:13 -04001579 case MSG_USER_INFO_CHANGED:
1580 handleUserInfoChanged(msg.arg1);
1581 break;
1582 case MSG_REPORT_EMERGENCY_CALL_ACTION:
1583 handleReportEmergencyCallAction();
1584 break;
1585 case MSG_STARTED_GOING_TO_SLEEP:
1586 handleStartedGoingToSleep(msg.arg1);
1587 break;
1588 case MSG_FINISHED_GOING_TO_SLEEP:
1589 handleFinishedGoingToSleep(msg.arg1);
1590 break;
1591 case MSG_STARTED_WAKING_UP:
1592 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_STARTED_WAKING_UP");
1593 handleStartedWakingUp();
1594 Trace.endSection();
1595 break;
1596 case MSG_FACE_UNLOCK_STATE_CHANGED:
1597 Trace.beginSection(
1598 "KeyguardUpdateMonitor#handler MSG_FACE_UNLOCK_STATE_CHANGED");
1599 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
1600 Trace.endSection();
1601 break;
1602 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
1603 handleSimSubscriptionInfoChanged();
1604 break;
1605 case MSG_AIRPLANE_MODE_CHANGED:
1606 handleAirplaneModeChanged();
1607 break;
1608 case MSG_SERVICE_STATE_CHANGE:
1609 handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
1610 break;
1611 case MSG_SCREEN_TURNED_ON:
1612 handleScreenTurnedOn();
1613 break;
1614 case MSG_SCREEN_TURNED_OFF:
1615 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_SCREEN_TURNED_ON");
1616 handleScreenTurnedOff();
1617 Trace.endSection();
1618 break;
1619 case MSG_DREAMING_STATE_CHANGED:
1620 handleDreamingStateChanged(msg.arg1);
1621 break;
1622 case MSG_USER_UNLOCKED:
1623 handleUserUnlocked(msg.arg1);
1624 break;
1625 case MSG_USER_STOPPED:
1626 handleUserStopped(msg.arg1);
1627 break;
1628 case MSG_USER_REMOVED:
1629 handleUserRemoved(msg.arg1);
1630 break;
1631 case MSG_ASSISTANT_STACK_CHANGED:
1632 setAssistantVisible((boolean) msg.obj);
1633 break;
1634 case MSG_BIOMETRIC_AUTHENTICATION_CONTINUE:
1635 updateBiometricListeningState();
1636 break;
1637 case MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED:
1638 updateLogoutEnabled();
1639 break;
1640 case MSG_TELEPHONY_CAPABLE:
1641 updateTelephonyCapable((boolean) msg.obj);
1642 break;
1643 default:
1644 super.handleMessage(msg);
1645 break;
1646 }
1647 }
1648 };
1649
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001650 // Since device can't be un-provisioned, we only need to register a content observer
1651 // to update mDeviceProvisioned when we are...
1652 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001653 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001654 }
Jim Miller47088bb2009-11-24 00:40:16 -08001655
Jim Millerbbf1a742012-07-17 18:30:30 -07001656 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Adrian Roos7b043112015-07-10 13:00:33 -07001657 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001658
Jim Millerbbf1a742012-07-17 18:30:30 -07001659 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001660 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001661 filter.addAction(Intent.ACTION_TIME_TICK);
1662 filter.addAction(Intent.ACTION_TIME_CHANGED);
1663 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
1664 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Jason Monk052082c2015-06-11 11:35:23 -04001665 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
Daniel Bright350f7f92020-01-22 14:24:11 -08001666 filter.addAction(Intent.ACTION_SIM_STATE_CHANGED);
Jayachandran C041e7692019-12-20 16:20:02 -08001667 filter.addAction(Intent.ACTION_SERVICE_STATE);
1668 filter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -08001669 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Alex Chauff7653d2018-02-01 17:18:08 +00001670 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Beverly4e7dd9a2020-02-28 17:04:21 -05001671 mBroadcastDispatcher.registerReceiverWithHandler(mBroadcastReceiver, filter, mHandler);
Hall Liu45066122020-04-07 15:37:44 -07001672 // Since ACTION_SERVICE_STATE is being moved to a non-sticky broadcast, trigger the
1673 // listener now with the service state from the default sub.
1674 mBackgroundExecutor.execute(() -> {
1675 int subId = SubscriptionManager.getDefaultSubscriptionId();
1676 ServiceState serviceState = mContext.getSystemService(TelephonyManager.class)
1677 .getServiceStateForSubscriber(subId);
1678 mHandler.sendMessage(
1679 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
1680 });
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001681
Fabian Kozynskib6a20372020-04-01 09:36:43 -04001682 mHandler.post(this::registerRingerTracker);
1683
Adrian Roos48c796c2014-09-01 14:59:23 +02001684 final IntentFilter allUserFilter = new IntentFilter();
1685 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
1686 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
1687 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
1688 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
1689 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001690 allUserFilter.addAction(ACTION_USER_UNLOCKED);
Lucas Dupin6c6d5732019-08-27 17:36:05 -07001691 allUserFilter.addAction(ACTION_USER_STOPPED);
1692 allUserFilter.addAction(ACTION_USER_REMOVED);
Beverly4e7dd9a2020-02-28 17:04:21 -05001693 mBroadcastDispatcher.registerReceiverWithHandler(mBroadcastAllReceiver, allUserFilter,
Fabian Kozynski5e92c6f2020-01-03 13:56:17 -05001694 mHandler, UserHandle.ALL);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001695
Wink Saville071743f2015-01-12 17:11:04 -08001696 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001697 try {
Beverly4e7dd9a2020-02-28 17:04:21 -05001698 ActivityManager.getService().registerUserSwitchObserver(mUserSwitchObserver, TAG);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001699 } catch (RemoteException e) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001700 e.rethrowAsRuntimeException();
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001701 }
Adrian Roos46842d92014-03-27 14:58:03 +01001702
Lucas Dupinf2c53502019-10-03 13:56:18 -07001703 mTrustManager = context.getSystemService(TrustManager.class);
Jorim Jaggi237b0612015-05-01 14:28:49 -07001704 mTrustManager.registerTrustListener(this);
Michal Karpinskic52f8672016-11-18 11:32:45 +00001705 mLockPatternUtils = new LockPatternUtils(context);
1706 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Jim Millerf41fc962014-06-18 16:33:51 -07001707
Kevin Chyn36778ff2017-09-07 19:55:38 -07001708 mDreamManager = IDreamManager.Stub.asInterface(
1709 ServiceManager.getService(DreamService.DREAM_SERVICE));
1710
Jorim Jaggi3f124262016-11-22 13:45:17 +01001711 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
1712 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
1713 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001714 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
Kevin Chynb7b54a62018-09-28 18:48:12 -07001715 mFaceManager = (FaceManager) context.getSystemService(Context.FACE_SERVICE);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001716 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07001717
1718 if (mFpm != null || mFaceManager != null) {
1719 mBiometricManager = context.getSystemService(BiometricManager.class);
1720 mBiometricManager.registerEnabledOnKeyguardCallback(mBiometricEnabledCallback);
1721 }
1722
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001723 updateBiometricListeningState();
Jorim Jaggi3a464782015-08-28 16:59:13 -07001724 if (mFpm != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001725 mFpm.addLockoutResetCallback(mFingerprintLockoutResetCallback);
1726 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07001727 if (mFaceManager != null) {
1728 mFaceManager.addLockoutResetCallback(mFaceLockoutResetCallback);
Jorim Jaggi3a464782015-08-28 16:59:13 -07001729 }
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001730
Winson Chung2cf6ad82017-11-09 17:36:59 -08001731 ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001732 mUserManager = context.getSystemService(UserManager.class);
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001733 mIsPrimaryUser = mUserManager.isPrimaryUser();
Lucas Dupin6c6d5732019-08-27 17:36:05 -07001734 int user = ActivityManager.getCurrentUser();
1735 mUserIsUnlocked.put(user, mUserManager.isUserUnlocked(user));
Alex Chauff7653d2018-02-01 17:18:08 +00001736 mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
1737 mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
Yvonne Jiangb7024a22019-12-05 16:57:08 -08001738 updateSecondaryLockscreenRequirement(user);
Lucas Dupinf2c53502019-10-03 13:56:18 -07001739 List<UserInfo> allUsers = mUserManager.getUsers();
1740 for (UserInfo userInfo : allUsers) {
1741 mUserTrustIsUsuallyManaged.put(userInfo.id,
1742 mTrustManager.isTrustUsuallyManaged(userInfo.id));
1743 }
Bill Linef81cbd2018-07-05 17:48:49 +08001744 updateAirplaneModeState();
Fabian Kozynskiccde55d2019-06-26 10:06:09 -04001745
Fabian Kozynskib00c70b2020-04-03 12:41:31 -04001746 mTelephonyManager =
Fabian Kozynskiccde55d2019-06-26 10:06:09 -04001747 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Fabian Kozynskib00c70b2020-04-03 12:41:31 -04001748 if (mTelephonyManager != null) {
1749 mTelephonyManager.listen(mPhoneStateListener,
1750 LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
1751 // Set initial sim states values.
1752 for (int slot = 0; slot < mTelephonyManager.getActiveModemCount(); slot++) {
1753 int state = mTelephonyManager.getSimState(slot);
1754 int[] subIds = mSubscriptionManager.getSubscriptionIds(slot);
1755 if (subIds != null) {
1756 for (int subId : subIds) {
1757 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, subId, slot, state)
1758 .sendToTarget();
1759 }
1760 }
1761 }
Fabian Kozynskiccde55d2019-06-26 10:06:09 -04001762 }
Bill Linef81cbd2018-07-05 17:48:49 +08001763 }
1764
Beverly4e7dd9a2020-02-28 17:04:21 -05001765 private final UserSwitchObserver mUserSwitchObserver = new UserSwitchObserver() {
1766 @Override
1767 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
1768 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
1769 newUserId, 0, reply));
1770 }
1771
1772 @Override
1773 public void onUserSwitchComplete(int newUserId) throws RemoteException {
1774 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
1775 newUserId, 0));
1776 }
1777 };
1778
Bill Linef81cbd2018-07-05 17:48:49 +08001779 private void updateAirplaneModeState() {
1780 // ACTION_AIRPLANE_MODE_CHANGED do not broadcast if device set AirplaneMode ON and boot
1781 if (!WirelessUtils.isAirplaneModeOn(mContext)
1782 || mHandler.hasMessages(MSG_AIRPLANE_MODE_CHANGED)) {
1783 return;
1784 }
1785 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Jorim Jaggiea657062015-04-28 13:45:11 -07001786 }
1787
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001788 private void updateBiometricListeningState() {
1789 updateFingerprintListeningState();
1790 updateFaceListeningState();
1791 }
1792
Jorim Jaggiea657062015-04-28 13:45:11 -07001793 private void updateFingerprintListeningState() {
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001794 // If this message exists, we should not authenticate again until this message is
1795 // consumed by the handler
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001796 if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001797 return;
1798 }
Kevin Chyn0c45b072017-04-24 16:27:11 -07001799 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
Jorim Jaggiea657062015-04-28 13:45:11 -07001800 boolean shouldListenForFingerprint = shouldListenForFingerprint();
Adrian Roos2aaf9442018-11-20 16:57:33 +01001801 boolean runningOrRestarting = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING
1802 || mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING;
1803 if (runningOrRestarting && !shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001804 stopListeningForFingerprint();
Adrian Roos2aaf9442018-11-20 16:57:33 +01001805 } else if (!runningOrRestarting && shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001806 startListeningForFingerprint();
1807 }
1808 }
1809
Lucas Dupin3d053532019-01-29 12:35:22 -08001810 /**
Lucas Dupin6c6d5732019-08-27 17:36:05 -07001811 * If a user is encrypted or not.
1812 * This is NOT related to the lock screen being visible or not.
1813 *
1814 * @param userId The user.
1815 * @return {@code true} when encrypted.
1816 * @see UserManager#isUserUnlocked()
1817 * @see Intent#ACTION_USER_UNLOCKED
1818 */
1819 public boolean isUserUnlocked(int userId) {
1820 return mUserIsUnlocked.get(userId);
1821 }
1822
1823 /**
Lucas Dupine0516d52019-02-05 17:54:06 -05001824 * Called whenever passive authentication is requested or aborted by a sensor.
Dave Mankoff4b0ab652019-08-07 09:49:20 -04001825 *
Lucas Dupine0516d52019-02-05 17:54:06 -05001826 * @param active If the interrupt started or ended.
Lucas Dupin3d053532019-01-29 12:35:22 -08001827 */
Lucas Dupine0516d52019-02-05 17:54:06 -05001828 public void onAuthInterruptDetected(boolean active) {
1829 if (DEBUG) Log.d(TAG, "onAuthInterruptDetected(" + active + ")");
1830 if (mAuthInterruptActive == active) {
1831 return;
1832 }
1833 mAuthInterruptActive = active;
Lucas Dupin3d053532019-01-29 12:35:22 -08001834 updateFaceListeningState();
1835 }
1836
Lucas Dupin8f3faac2019-03-12 15:28:49 -07001837 /**
1838 * Requests face authentication if we're on a state where it's allowed.
1839 * This will re-trigger auth in case it fails.
1840 */
1841 public void requestFaceAuth() {
1842 if (DEBUG) Log.d(TAG, "requestFaceAuth()");
1843 updateFaceListeningState();
1844 }
1845
Lucas Dupinccf67212019-08-07 12:53:02 -07001846 /**
1847 * In case face auth is running, cancel it.
1848 */
1849 public void cancelFaceAuth() {
1850 stopListeningForFace();
1851 }
1852
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001853 private void updateFaceListeningState() {
1854 // If this message exists, we should not authenticate again until this message is
1855 // consumed by the handler
1856 if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
1857 return;
1858 }
1859 mHandler.removeCallbacks(mRetryFaceAuthentication);
1860 boolean shouldListenForFace = shouldListenForFace();
1861 if (mFaceRunningState == BIOMETRIC_STATE_RUNNING && !shouldListenForFace) {
1862 stopListeningForFace();
Curtis Belmonte9dc68152020-05-08 17:12:13 -07001863 } else if (mFaceRunningState != BIOMETRIC_STATE_RUNNING && shouldListenForFace) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001864 startListeningForFace();
1865 }
1866 }
1867
Kevin Chyn129f60f2017-08-11 17:24:42 -07001868 private boolean shouldListenForFingerprintAssistant() {
Haining Chenc06c4812020-01-13 20:38:53 -08001869 BiometricAuthenticated fingerprint = mUserFingerprintAuthenticated.get(getCurrentUser());
Kevin Chyn129f60f2017-08-11 17:24:42 -07001870 return mAssistantVisible && mKeyguardOccluded
Haining Chenc06c4812020-01-13 20:38:53 -08001871 && !(fingerprint != null && fingerprint.mAuthenticated)
Kevin Chyn129f60f2017-08-11 17:24:42 -07001872 && !mUserHasTrust.get(getCurrentUser(), false);
1873 }
1874
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001875 private boolean shouldListenForFaceAssistant() {
Haining Chenc06c4812020-01-13 20:38:53 -08001876 BiometricAuthenticated face = mUserFaceAuthenticated.get(getCurrentUser());
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001877 return mAssistantVisible && mKeyguardOccluded
Haining Chenc06c4812020-01-13 20:38:53 -08001878 && !(face != null && face.mAuthenticated)
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001879 && !mUserHasTrust.get(getCurrentUser(), false);
1880 }
1881
Jorim Jaggiea657062015-04-28 13:45:11 -07001882 private boolean shouldListenForFingerprint() {
Kevin Chyn8ae64b52020-04-06 15:48:49 -07001883 final boolean allowedOnBouncer =
1884 !(mFingerprintLockedOut && mBouncer && mCredentialAttempted);
1885
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001886 // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
1887 // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
1888 final boolean shouldListen = (mKeyguardIsVisible || !mDeviceInteractive ||
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001889 (mBouncer && !mKeyguardGoingAway) || mGoingToSleep ||
Kevin Chyn36778ff2017-09-07 19:55:38 -07001890 shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming))
Lucas Dupinc12fad32019-05-14 20:59:17 +00001891 && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser())
Kevin Chyn8ae64b52020-04-06 15:48:49 -07001892 && (!mKeyguardGoingAway || !mDeviceInteractive) && mIsPrimaryUser
1893 && allowedOnBouncer;
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001894 return shouldListen;
Jim Miller9f0753f2015-03-23 23:59:22 -07001895 }
1896
Lucas Dupin4b75b192019-08-29 14:46:29 -07001897 /**
1898 * If face auth is allows to scan on this exact moment.
1899 */
1900 public boolean shouldListenForFace() {
Curtis Belmonte9dc68152020-05-08 17:12:13 -07001901 final boolean statusBarShadeLocked =
1902 mStatusBarStateController.getState() == StatusBarState.SHADE_LOCKED;
1903 final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep
1904 && !statusBarShadeLocked;
Lucas Dupin3d053532019-01-29 12:35:22 -08001905 final int user = getCurrentUser();
Robert Snoeberger5dcdf352019-06-24 11:28:28 -04001906 final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user);
Curtis Belmontec47df862020-01-28 16:58:34 -08001907 final boolean isLockDown =
1908 containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW)
Lucas Dupin8eec2682019-07-01 16:41:17 -07001909 || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
1910 final boolean isEncryptedOrTimedOut =
1911 containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_BOOT)
1912 || containsFlag(strongAuth, STRONG_AUTH_REQUIRED_AFTER_TIMEOUT);
Lucas Dupin9e484aa2019-06-24 13:38:00 -07001913
Lucas Dupin4befb742019-07-01 11:31:31 -07001914 boolean canBypass = mKeyguardBypassController != null
1915 && mKeyguardBypassController.canBypass();
Lucas Dupin9e484aa2019-06-24 13:38:00 -07001916 // There's no reason to ask the HAL for authentication when the user can dismiss the
1917 // bouncer, unless we're bypassing and need to auto-dismiss the lock screen even when
1918 // TrustAgents or biometrics are keeping the device unlocked.
Lucas Dupin4befb742019-07-01 11:31:31 -07001919 boolean becauseCannotSkipBouncer = !getUserCanSkipBouncer(user) || canBypass;
Lucas Dupin9e484aa2019-06-24 13:38:00 -07001920
Lucas Dupin8eec2682019-07-01 16:41:17 -07001921 // Scan even when encrypted or timeout to show a preemptive bouncer when bypassing.
Curtis Belmontec47df862020-01-28 16:58:34 -08001922 // Lock-down mode shouldn't scan, since it is more explicit.
Lucas Dupin8eec2682019-07-01 16:41:17 -07001923 boolean strongAuthAllowsScanning = (!isEncryptedOrTimedOut || canBypass && !mBouncer)
Curtis Belmontec47df862020-01-28 16:58:34 -08001924 && !isLockDown;
Lucas Dupin8eec2682019-07-01 16:41:17 -07001925
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001926 // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
1927 // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
Kevin Chyn505eb892020-03-26 13:07:03 -07001928 final boolean shouldListen =
1929 (mBouncer || mAuthInterruptActive || awakeKeyguard
1930 || shouldListenForFaceAssistant())
Lucas Dupin9e484aa2019-06-24 13:38:00 -07001931 && !mSwitchingUser && !isFaceDisabled(user) && becauseCannotSkipBouncer
Lucas Dupin7d95f152019-07-17 16:25:54 -07001932 && !mKeyguardGoingAway && mFaceSettingEnabledForUser.get(user) && !mLockIconPressed
Lucas Dupin8eec2682019-07-01 16:41:17 -07001933 && strongAuthAllowsScanning && mIsPrimaryUser
1934 && !mSecureCameraLaunched;
Kevin Chyn505eb892020-03-26 13:07:03 -07001935
1936 // Too chatty, but very useful when debugging issues.
1937 if (DEBUG_SPEW) {
1938 Log.v(TAG, "shouldListenForFace(" + user + ")=" + shouldListen + "... "
1939 + ", mBouncer: " + mBouncer
1940 + ", mAuthInterruptActive: " + mAuthInterruptActive
1941 + ", awakeKeyguard: " + awakeKeyguard
1942 + ", shouldListenForFaceAssistant: " + shouldListenForFaceAssistant()
1943 + ", mSwitchingUser: " + mSwitchingUser
1944 + ", isFaceDisabled(" + user + "): " + isFaceDisabled(user)
1945 + ", becauseCannotSkipBouncer: " + becauseCannotSkipBouncer
1946 + ", mKeyguardGoingAway: " + mKeyguardGoingAway
1947 + ", mFaceSettingEnabledForUser(" + user + "): "
1948 + mFaceSettingEnabledForUser.get(user)
1949 + ", mLockIconPressed: " + mLockIconPressed
1950 + ", strongAuthAllowsScanning: " + strongAuthAllowsScanning
1951 + ", isPrimaryUser: " + mIsPrimaryUser
1952 + ", mSecureCameraLaunched: " + mSecureCameraLaunched);
1953 }
1954 return shouldListen;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001955 }
1956
Lucas Dupinca88e5f2019-05-14 16:11:08 -07001957 /**
1958 * Whenever the lock icon is long pressed, disabling trust agents.
1959 * This means that we cannot auth passively (face) until the user presses power.
1960 */
1961 public void onLockIconPressed() {
1962 mLockIconPressed = true;
Curtis Belmontec48eff52019-08-21 15:51:34 -07001963 final int userId = getCurrentUser();
Haining Chenc06c4812020-01-13 20:38:53 -08001964 mUserFaceAuthenticated.put(userId, null);
Lucas Dupinca88e5f2019-05-14 16:11:08 -07001965 updateFaceListeningState();
Curtis Belmontec48eff52019-08-21 15:51:34 -07001966 mStrongAuthTracker.onStrongAuthRequiredChanged(userId);
Lucas Dupinca88e5f2019-05-14 16:11:08 -07001967 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001968
Jim Millerce7eb6d2015-04-03 19:29:13 -07001969 private void startListeningForFingerprint() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001970 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING) {
1971 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001972 return;
1973 }
Adrian Roos2aaf9442018-11-20 16:57:33 +01001974 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1975 // Waiting for restart via handleFingerprintError().
1976 return;
1977 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001978 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Lucas Dupin8f3faac2019-03-12 15:28:49 -07001979 int userId = getCurrentUser();
Jorim Jaggi71448a72015-08-18 19:49:04 -07001980 if (isUnlockWithFingerprintPossible(userId)) {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001981 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001982 mFingerprintCancelSignal.cancel();
1983 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001984 mFingerprintCancelSignal = new CancellationSignal();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001985 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mFingerprintAuthenticationCallback,
1986 null, userId);
1987 setFingerprintRunningState(BIOMETRIC_STATE_RUNNING);
1988 }
1989 }
1990
1991 private void startListeningForFace() {
1992 if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING) {
1993 setFaceRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);
1994 return;
1995 }
1996 if (DEBUG) Log.v(TAG, "startListeningForFace()");
Lucas Dupin8f3faac2019-03-12 15:28:49 -07001997 int userId = getCurrentUser();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001998 if (isUnlockWithFacePossible(userId)) {
1999 if (mFaceCancelSignal != null) {
2000 mFaceCancelSignal.cancel();
2001 }
2002 mFaceCancelSignal = new CancellationSignal();
Kevin Chynb7b54a62018-09-28 18:48:12 -07002003 mFaceManager.authenticate(null, mFaceCancelSignal, 0,
Kevin Chyn8d2694a2019-04-11 18:30:40 -07002004 mFaceAuthenticationCallback, null, userId);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002005 setFaceRunningState(BIOMETRIC_STATE_RUNNING);
Jim Miller9f0753f2015-03-23 23:59:22 -07002006 }
2007 }
2008
Lucas Dupin8d48fc42019-04-25 14:34:12 -07002009 /**
2010 * If biometrics hardware is available, not disabled, and user has enrolled templates.
2011 * This does NOT check if the device is encrypted or in lockdown.
2012 *
2013 * @param userId User that's trying to unlock.
2014 * @return {@code true} if possible.
2015 */
2016 public boolean isUnlockingWithBiometricsPossible(int userId) {
2017 return isUnlockWithFacePossible(userId) || isUnlockWithFingerprintPossible(userId);
2018 }
2019
2020 private boolean isUnlockWithFingerprintPossible(int userId) {
Selim Cinek3122fa82015-06-18 01:38:59 -07002021 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
2022 && mFpm.getEnrolledFingerprints(userId).size() > 0;
2023 }
2024
Lucas Dupin4c507042019-07-22 16:47:34 -07002025 private boolean isUnlockWithFacePossible(int userId) {
2026 return isFaceAuthEnabledForUser(userId) && !isFaceDisabled(userId);
2027 }
2028
Lucas Dupin7156bc72019-05-03 19:37:39 -07002029 /**
Lucas Dupin7d95f152019-07-17 16:25:54 -07002030 * If face hardware is available, user has enrolled and enabled auth via setting.
Lucas Dupin7156bc72019-05-03 19:37:39 -07002031 */
Lucas Dupin4c507042019-07-22 16:47:34 -07002032 public boolean isFaceAuthEnabledForUser(int userId) {
Lucas Dupin8968f6a2019-08-09 17:41:15 -07002033 // TODO(b/140034352)
2034 return whitelistIpcs(() -> mFaceManager != null && mFaceManager.isHardwareDetected()
Lucas Dupin7d95f152019-07-17 16:25:54 -07002035 && mFaceManager.hasEnrolledTemplates(userId)
Lucas Dupin8968f6a2019-08-09 17:41:15 -07002036 && mFaceSettingEnabledForUser.get(userId));
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002037 }
2038
Jorim Jaggiea657062015-04-28 13:45:11 -07002039 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -07002040 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002041 if (mFingerprintRunningState == BIOMETRIC_STATE_RUNNING) {
Kevin Chyn2fefd462017-04-28 12:18:19 -07002042 if (mFingerprintCancelSignal != null) {
2043 mFingerprintCancelSignal.cancel();
2044 mFingerprintCancelSignal = null;
joshmccloskey7dee4542019-07-31 18:35:33 -07002045 if (!mHandler.hasCallbacks(mCancelNotReceived)) {
2046 mHandler.postDelayed(mCancelNotReceived, DEFAULT_CANCEL_SIGNAL_TIMEOUT);
2047 }
Kevin Chyn2fefd462017-04-28 12:18:19 -07002048 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002049 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING);
Jim Miller9f0753f2015-03-23 23:59:22 -07002050 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002051 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
2052 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING);
2053 }
2054 }
2055
2056 private void stopListeningForFace() {
2057 if (DEBUG) Log.v(TAG, "stopListeningForFace()");
2058 if (mFaceRunningState == BIOMETRIC_STATE_RUNNING) {
2059 if (mFaceCancelSignal != null) {
2060 mFaceCancelSignal.cancel();
2061 mFaceCancelSignal = null;
joshmccloskey7dee4542019-07-31 18:35:33 -07002062 if (!mHandler.hasCallbacks(mCancelNotReceived)) {
2063 mHandler.postDelayed(mCancelNotReceived, DEFAULT_CANCEL_SIGNAL_TIMEOUT);
2064 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002065 }
2066 setFaceRunningState(BIOMETRIC_STATE_CANCELLING);
2067 }
2068 if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
2069 setFaceRunningState(BIOMETRIC_STATE_CANCELLING);
Jorim Jaggi86bed402015-08-20 18:20:02 -07002070 }
Jim Millerbbf1a742012-07-17 18:30:30 -07002071 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002072
Michael Jurkafff56142012-11-28 16:51:00 -08002073 private boolean isDeviceProvisionedInSettingsDb() {
2074 return Settings.Global.getInt(mContext.getContentResolver(),
2075 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
2076 }
2077
Jim Millerbbf1a742012-07-17 18:30:30 -07002078 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -08002079 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002080 @Override
2081 public void onChange(boolean selfChange) {
2082 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -08002083 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07002084 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07002085 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002086 }
Jim Millerbbf1a742012-07-17 18:30:30 -07002087 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002088 }
Jim Millerbbf1a742012-07-17 18:30:30 -07002089 };
2090
2091 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -07002092 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -08002093 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -07002094
2095 // prevent a race condition between where we check the flag and where we register the
2096 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -08002097 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07002098 if (provisioned != mDeviceProvisioned) {
2099 mDeviceProvisioned = provisioned;
2100 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07002101 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -07002102 }
2103 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002104 }
2105
Jim Millerbbf1a742012-07-17 18:30:30 -07002106 /**
Jorim Jaggid11d1a92016-08-16 16:02:32 -07002107 * Update the state whether Keyguard currently has a lockscreen wallpaper.
2108 *
2109 * @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper.
2110 */
2111 public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) {
Beverly1467c9e2020-02-18 13:31:29 -05002112 Assert.isMainThread();
Jorim Jaggid11d1a92016-08-16 16:02:32 -07002113 if (hasLockscreenWallpaper != mHasLockscreenWallpaper) {
2114 mHasLockscreenWallpaper = hasLockscreenWallpaper;
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002115 for (int i = 0; i < mCallbacks.size(); i++) {
Jorim Jaggid11d1a92016-08-16 16:02:32 -07002116 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2117 if (cb != null) {
2118 cb.onHasLockscreenWallpaperChanged(hasLockscreenWallpaper);
2119 }
2120 }
2121 }
2122 }
2123
2124 /**
2125 * @return Whether Keyguard has a lockscreen wallpaper.
2126 */
2127 public boolean hasLockscreenWallpaper() {
2128 return mHasLockscreenWallpaper;
2129 }
2130
2131 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07002132 * Handle {@link #MSG_DPM_STATE_CHANGED}
2133 */
Yvonne Jiangb7024a22019-12-05 16:57:08 -08002134 private void handleDevicePolicyManagerStateChanged(int userId) {
Beverly1467c9e2020-02-18 13:31:29 -05002135 Assert.isMainThread();
Adrian Roos733b6632015-08-21 14:32:35 -07002136 updateFingerprintListeningState();
Yvonne Jiangb7024a22019-12-05 16:57:08 -08002137 updateSecondaryLockscreenRequirement(userId);
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002138 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002139 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2140 if (cb != null) {
2141 cb.onDevicePolicyManagerStateChanged();
2142 }
Jim Millerb0304762012-03-13 20:01:25 -07002143 }
2144 }
2145
Jim Millerbbf1a742012-07-17 18:30:30 -07002146 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05002147 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -07002148 */
Kevin Chyn505eb892020-03-26 13:07:03 -07002149 @VisibleForTesting
2150 void handleUserSwitching(int userId, IRemoteCallback reply) {
Beverly1467c9e2020-02-18 13:31:29 -05002151 Assert.isMainThread();
Kevin Chyn505eb892020-03-26 13:07:03 -07002152 clearBiometricRecognized();
Lucas Dupinf2c53502019-10-03 13:56:18 -07002153 mUserTrustIsUsuallyManaged.put(userId, mTrustManager.isTrustUsuallyManaged(userId));
Jim Millerbbf1a742012-07-17 18:30:30 -07002154 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002155 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2156 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05002157 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -07002158 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07002159 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07002160 try {
2161 reply.sendResult(null);
2162 } catch (RemoteException e) {
2163 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07002164 }
2165
Jim Millerbbf1a742012-07-17 18:30:30 -07002166 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05002167 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
2168 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02002169 private void handleUserSwitchComplete(int userId) {
Beverly1467c9e2020-02-18 13:31:29 -05002170 Assert.isMainThread();
Chris Wrenf41c61b2012-11-29 15:19:54 -05002171 for (int i = 0; i < mCallbacks.size(); i++) {
2172 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2173 if (cb != null) {
2174 cb.onUserSwitchComplete(userId);
2175 }
2176 }
2177 }
2178
2179 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07002180 * Handle {@link #MSG_DEVICE_PROVISIONED}
2181 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02002182 private void handleDeviceProvisioned() {
Beverly1467c9e2020-02-18 13:31:29 -05002183 Assert.isMainThread();
Jim Millerbbf1a742012-07-17 18:30:30 -07002184 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002185 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2186 if (cb != null) {
2187 cb.onDeviceProvisioned();
2188 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -07002189 }
Michael Jurkafff56142012-11-28 16:51:00 -08002190 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -07002191 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -08002192 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
2193 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -07002194 }
2195 }
2196
Jim Millerbbf1a742012-07-17 18:30:30 -07002197 /**
2198 * Handle {@link #MSG_PHONE_STATE_CHANGED}
2199 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02002200 private void handlePhoneStateChanged(String newState) {
Beverly1467c9e2020-02-18 13:31:29 -05002201 Assert.isMainThread();
Jim Millerc23024d2010-02-24 15:37:00 -08002202 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07002203 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
2204 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
2205 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
2206 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
2207 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
2208 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
2209 }
Jim Millerbbf1a742012-07-17 18:30:30 -07002210 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002211 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2212 if (cb != null) {
2213 cb.onPhoneStateChanged(mPhoneState);
2214 }
Jim Millerc23024d2010-02-24 15:37:00 -08002215 }
2216 }
2217
Jim Millerbbf1a742012-07-17 18:30:30 -07002218 /**
2219 * Handle {@link #MSG_RINGER_MODE_CHANGED}
2220 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02002221 private void handleRingerModeChange(int mode) {
Beverly1467c9e2020-02-18 13:31:29 -05002222 Assert.isMainThread();
Jim Miller47088bb2009-11-24 00:40:16 -08002223 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07002224 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -07002225 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002226 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2227 if (cb != null) {
2228 cb.onRingerModeChanged(mode);
2229 }
Jim Miller47088bb2009-11-24 00:40:16 -08002230 }
2231 }
2232
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002233 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002234 * Handle {@link #MSG_TIME_UPDATE}
2235 */
2236 private void handleTimeUpdate() {
Beverly1467c9e2020-02-18 13:31:29 -05002237 Assert.isMainThread();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002238 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07002239 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002240 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2241 if (cb != null) {
2242 cb.onTimeChanged();
2243 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002244 }
2245 }
2246
2247 /**
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05002248 * Handle (@line #MSG_TIMEZONE_UPDATE}
2249 */
2250 private void handleTimeZoneUpdate(String timeZone) {
Beverly1467c9e2020-02-18 13:31:29 -05002251 Assert.isMainThread();
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05002252 if (DEBUG) Log.d(TAG, "handleTimeZoneUpdate");
2253 for (int i = 0; i < mCallbacks.size(); i++) {
2254 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2255 if (cb != null) {
2256 cb.onTimeZoneChanged(TimeZone.getTimeZone(timeZone));
2257 // Also notify callbacks about time change to remain compatible.
2258 cb.onTimeChanged();
2259 }
2260 }
2261 }
2262
2263 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002264 * Handle {@link #MSG_BATTERY_UPDATE}
2265 */
Jim Millerbbf1a742012-07-17 18:30:30 -07002266 private void handleBatteryUpdate(BatteryStatus status) {
Beverly1467c9e2020-02-18 13:31:29 -05002267 Assert.isMainThread();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002268 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07002269 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
2270 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07002271 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002272 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002273 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2274 if (cb != null) {
2275 cb.onRefreshBatteryInfo(status);
2276 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002277 }
2278 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002279 }
2280
2281 /**
Bill Linef81cbd2018-07-05 17:48:49 +08002282 * Handle Telephony status during Boot for CarrierText display policy
2283 */
2284 @VisibleForTesting
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002285 void updateTelephonyCapable(boolean capable) {
Beverly1467c9e2020-02-18 13:31:29 -05002286 Assert.isMainThread();
Bill Linef81cbd2018-07-05 17:48:49 +08002287 if (capable == mTelephonyCapable) {
2288 return;
2289 }
2290 mTelephonyCapable = capable;
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002291 for (int i = 0; i < mCallbacks.size(); i++) {
2292 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
Bill Linef81cbd2018-07-05 17:48:49 +08002293 if (cb != null) {
2294 cb.onTelephonyCapable(mTelephonyCapable);
2295 }
2296 }
2297 }
2298
2299 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002300 * Handle {@link #MSG_SIM_STATE_CHANGE}
2301 */
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08002302 @VisibleForTesting
Jayachandran Cf5436a62019-11-08 18:22:45 -08002303 void handleSimStateChange(int subId, int slotId, int state) {
Beverly1467c9e2020-02-18 13:31:29 -05002304 Assert.isMainThread();
Jim Miller52a61332014-11-12 19:29:51 -08002305 if (DEBUG_SIM_STATES) {
2306 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002307 + slotId + ", state=" + state + ")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002308 }
2309
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002310 boolean becameAbsent = false;
Wink Savillea54bf652014-12-11 13:37:50 -08002311 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08002312 Log.w(TAG, "invalid subId in handleSimStateChange()");
andychou695a7602019-05-16 23:14:00 +08002313 /* Only handle No SIM(ABSENT) and Card Error(CARD_IO_ERROR) due to
2314 * handleServiceStateChange() handle other case */
Jayachandran Cf5436a62019-11-08 18:22:45 -08002315 if (state == TelephonyManager.SIM_STATE_ABSENT) {
Bill Linef81cbd2018-07-05 17:48:49 +08002316 updateTelephonyCapable(true);
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002317 // Even though the subscription is not valid anymore, we need to notify that the
2318 // SIM card was removed so we can update the UI.
2319 becameAbsent = true;
Brad Ebingere6c6f722018-12-20 21:11:44 -08002320 for (SimData data : mSimDatas.values()) {
2321 // Set the SIM state of all SimData associated with that slot to ABSENT se we
2322 // do not move back into PIN/PUK locked and not detect the change below.
2323 if (data.slotId == slotId) {
Jayachandran Cf5436a62019-11-08 18:22:45 -08002324 data.simState = TelephonyManager.SIM_STATE_ABSENT;
Brad Ebingere6c6f722018-12-20 21:11:44 -08002325 }
2326 }
Jayachandran Cf5436a62019-11-08 18:22:45 -08002327 } else if (state == TelephonyManager.SIM_STATE_CARD_IO_ERROR) {
andychou695a7602019-05-16 23:14:00 +08002328 updateTelephonyCapable(true);
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002329 } else {
2330 return;
Bill Linef81cbd2018-07-05 17:48:49 +08002331 }
Jim Miller52a61332014-11-12 19:29:51 -08002332 }
2333
2334 SimData data = mSimDatas.get(subId);
2335 final boolean changed;
2336 if (data == null) {
2337 data = new SimData(state, slotId, subId);
2338 mSimDatas.put(subId, data);
2339 changed = true; // no data yet; force update
2340 } else {
2341 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
2342 data.simState = state;
2343 data.subId = subId;
2344 data.slotId = slotId;
2345 }
Jayachandran Cf5436a62019-11-08 18:22:45 -08002346 if ((changed || becameAbsent) && state != TelephonyManager.SIM_STATE_UNKNOWN) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002347 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002348 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2349 if (cb != null) {
Jim Miller52a61332014-11-12 19:29:51 -08002350 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07002351 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002352 }
2353 }
2354 }
2355
Jim Millerbbf1a742012-07-17 18:30:30 -07002356 /**
Etan Cohen47051d82015-07-06 16:19:04 -07002357 * Handle {@link #MSG_SERVICE_STATE_CHANGE}
2358 */
Bill Linef81cbd2018-07-05 17:48:49 +08002359 @VisibleForTesting
2360 void handleServiceStateChange(int subId, ServiceState serviceState) {
Etan Cohen47051d82015-07-06 16:19:04 -07002361 if (DEBUG) {
2362 Log.d(TAG,
2363 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
2364 }
2365
2366 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2367 Log.w(TAG, "invalid subId in handleServiceStateChange()");
2368 return;
Bill Linef81cbd2018-07-05 17:48:49 +08002369 } else {
2370 updateTelephonyCapable(true);
Etan Cohen47051d82015-07-06 16:19:04 -07002371 }
2372
2373 mServiceStates.put(subId, serviceState);
2374
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002375 callbacksRefreshCarrierInfo();
Etan Cohen47051d82015-07-06 16:19:04 -07002376 }
2377
Lucas Dupinf8463ee2018-06-11 16:18:15 -07002378 public boolean isKeyguardVisible() {
2379 return mKeyguardIsVisible;
2380 }
2381
Etan Cohen47051d82015-07-06 16:19:04 -07002382 /**
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002383 * Notifies that the visibility state of Keyguard has changed.
2384 *
2385 * <p>Needs to be called from the main thread.
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002386 */
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002387 public void onKeyguardVisibilityChanged(boolean showing) {
Beverly1467c9e2020-02-18 13:31:29 -05002388 Assert.isMainThread();
Kevin Chynb4514d22019-04-15 13:47:25 -07002389 Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002390 mKeyguardIsVisible = showing;
Kevin Chyn6951d3d2019-06-10 14:07:13 -07002391
2392 if (showing) {
2393 mSecureCameraLaunched = false;
2394 }
2395
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002396 for (int i = 0; i < mCallbacks.size(); i++) {
2397 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2398 if (cb != null) {
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002399 cb.onKeyguardVisibilityChangedRaw(showing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002400 }
2401 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002402 updateBiometricListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002403 }
2404
Brian Colonna7fce3802013-09-17 15:51:32 -04002405 /**
Selim Cinek1fcafc42015-07-20 14:39:25 -07002406 * Handle {@link #MSG_KEYGUARD_RESET}
2407 */
2408 private void handleKeyguardReset() {
2409 if (DEBUG) Log.d(TAG, "handleKeyguardReset");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002410 updateBiometricListeningState();
Jorim Jaggi031f7952016-09-01 16:39:26 -07002411 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
2412 }
2413
2414 private boolean resolveNeedsSlowUnlockTransition() {
Lucas Dupin6c6d5732019-08-27 17:36:05 -07002415 if (isUserUnlocked(getCurrentUser())) {
Jorim Jaggi031f7952016-09-01 16:39:26 -07002416 return false;
2417 }
2418 Intent homeIntent = new Intent(Intent.ACTION_MAIN)
2419 .addCategory(Intent.CATEGORY_HOME);
2420 ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(homeIntent,
2421 0 /* flags */);
2422 return FALLBACK_HOME_COMPONENT.equals(resolveInfo.getComponentInfo().getComponentName());
Selim Cinek1fcafc42015-07-20 14:39:25 -07002423 }
2424
2425 /**
Adrian Roosb6011622014-05-14 15:52:53 +02002426 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002427 *
Adrian Roosb6011622014-05-14 15:52:53 +02002428 * @see #sendKeyguardBouncerChanged(boolean)
2429 */
2430 private void handleKeyguardBouncerChanged(int bouncer) {
Beverly1467c9e2020-02-18 13:31:29 -05002431 Assert.isMainThread();
Adrian Roosb6011622014-05-14 15:52:53 +02002432 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
2433 boolean isBouncer = (bouncer == 1);
2434 mBouncer = isBouncer;
Kevin Chynd0381892019-07-11 16:25:36 -07002435
2436 if (isBouncer) {
2437 // If the bouncer is shown, always clear this flag. This can happen in the following
2438 // situations: 1) Default camera with SHOW_WHEN_LOCKED is not chosen yet. 2) Secure
2439 // camera requests dismiss keyguard (tapping on photos for example). When these happen,
2440 // face auth should resume.
2441 mSecureCameraLaunched = false;
Kevin Chyn8ae64b52020-04-06 15:48:49 -07002442 } else {
2443 mCredentialAttempted = false;
Kevin Chynd0381892019-07-11 16:25:36 -07002444 }
2445
Adrian Roosb6011622014-05-14 15:52:53 +02002446 for (int i = 0; i < mCallbacks.size(); i++) {
2447 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2448 if (cb != null) {
2449 cb.onKeyguardBouncerChanged(isBouncer);
2450 }
2451 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002452 updateBiometricListeningState();
Adrian Roosb6011622014-05-14 15:52:53 +02002453 }
2454
2455 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04002456 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
2457 */
2458 private void handleReportEmergencyCallAction() {
Beverly1467c9e2020-02-18 13:31:29 -05002459 Assert.isMainThread();
Brian Colonna7fce3802013-09-17 15:51:32 -04002460 for (int i = 0; i < mCallbacks.size(); i++) {
2461 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2462 if (cb != null) {
2463 cb.onEmergencyCallAction();
2464 }
2465 }
2466 }
2467
Lucas Dupin4272f442018-01-13 22:00:35 -08002468 private boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002469 final boolean nowPluggedIn = current.isPluggedIn();
2470 final boolean wasPluggedIn = old.isPluggedIn();
Lucas Dupin4272f442018-01-13 22:00:35 -08002471 final boolean stateChangedWhilePluggedIn = wasPluggedIn && nowPluggedIn
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002472 && (old.status != current.status);
Jim Miller16464b82011-10-20 21:10:13 -07002473
2474 // change in plug state is always interesting
2475 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002476 return true;
2477 }
2478
Lucas Dupin3fcdd472018-01-19 19:06:45 -08002479 // change in battery level
2480 if (old.level != current.level) {
Jim Miller16464b82011-10-20 21:10:13 -07002481 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002482 }
Adrian Roos76dc5a52015-07-21 16:20:36 -07002483
2484 // change in charging current while plugged in
Adrian Roos0c859ae2015-11-23 16:47:50 -08002485 if (nowPluggedIn && current.maxChargingWattage != old.maxChargingWattage) {
Adrian Roos76dc5a52015-07-21 16:20:36 -07002486 return true;
2487 }
2488
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002489 return false;
2490 }
2491
2492 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07002493 * Remove the given observer's callback.
2494 *
Jim Miller6212cc02012-09-05 17:35:31 -07002495 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002496 */
Jim Miller6212cc02012-09-05 17:35:31 -07002497 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
Beverly1467c9e2020-02-18 13:31:29 -05002498 Assert.isMainThread();
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002499 if (DEBUG) {
2500 Log.v(TAG, "*** unregister callback for " + callback);
Jim Miller6212cc02012-09-05 17:35:31 -07002501 }
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002502
2503 mCallbacks.removeIf(el -> el.get() == callback);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002504 }
2505
2506 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002507 * Register to receive notifications about general keyguard information
2508 * (see {@link InfoCallback}.
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002509 *
Jim Miller6212cc02012-09-05 17:35:31 -07002510 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002511 */
Jim Millerbbf1a742012-07-17 18:30:30 -07002512 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Beverly1467c9e2020-02-18 13:31:29 -05002513 Assert.isMainThread();
Jim Miller6212cc02012-09-05 17:35:31 -07002514 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
2515 // Prevent adding duplicate callbacks
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002516
Jim Miller6212cc02012-09-05 17:35:31 -07002517 for (int i = 0; i < mCallbacks.size(); i++) {
2518 if (mCallbacks.get(i).get() == callback) {
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002519 if (DEBUG) {
2520 Log.e(TAG, "Object tried to add another callback",
2521 new Exception("Called by"));
2522 }
Jim Miller6212cc02012-09-05 17:35:31 -07002523 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07002524 }
2525 }
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002526 mCallbacks.add(new WeakReference<>(callback));
Jim Miller6212cc02012-09-05 17:35:31 -07002527 removeCallback(null); // remove unused references
2528 sendUpdates(callback);
2529 }
2530
Lucas Dupin9e484aa2019-06-24 13:38:00 -07002531 public void setKeyguardBypassController(KeyguardBypassController keyguardBypassController) {
2532 mKeyguardBypassController = keyguardBypassController;
2533 }
2534
Lucas Dupinc12fad32019-05-14 20:59:17 +00002535 public boolean isSwitchingUser() {
2536 return mSwitchingUser;
2537 }
2538
Adrian Roos30a2ae62018-04-25 19:09:50 +02002539 @AnyThread
Evan Rosky18396452016-07-27 15:19:37 -07002540 public void setSwitchingUser(boolean switching) {
Lucas Dupinc12fad32019-05-14 20:59:17 +00002541 mSwitchingUser = switching;
Selim Cinekbbe19242017-12-08 15:42:08 -08002542 // Since this comes in on a binder thread, we need to post if first
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002543 mHandler.post(mUpdateBiometricListeningState);
Evan Rosky18396452016-07-27 15:19:37 -07002544 }
2545
Jim Miller6212cc02012-09-05 17:35:31 -07002546 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
2547 // Notify listener of the current state
2548 callback.onRefreshBatteryInfo(mBatteryStatus);
2549 callback.onTimeChanged();
2550 callback.onRingerModeChanged(mRingMode);
2551 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05002552 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07002553 callback.onClockVisibilityChanged();
Lucas Dupin16cfe452018-02-08 13:14:50 -08002554 callback.onKeyguardVisibilityChangedRaw(mKeyguardIsVisible);
Bill Linef81cbd2018-07-05 17:48:49 +08002555 callback.onTelephonyCapable(mTelephonyCapable);
Jim Miller52a61332014-11-12 19:29:51 -08002556 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
2557 final SimData state = data.getValue();
2558 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
2559 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002560 }
2561
Selim Cinek1fcafc42015-07-20 14:39:25 -07002562 public void sendKeyguardReset() {
2563 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
2564 }
2565
Adrian Roosb6011622014-05-14 15:52:53 +02002566 /**
2567 * @see #handleKeyguardBouncerChanged(int)
2568 */
2569 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
2570 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
2571 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
2572 message.arg1 = showingBouncer ? 1 : 0;
2573 message.sendToTarget();
2574 }
2575
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002576 /**
Jim Miller90d5d462011-11-17 16:57:01 -08002577 * 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 -08002578 * have the information earlier than waiting for the intent
2579 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08002580 *
2581 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
2582 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002583 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02002584 @MainThread
Jim Miller52a61332014-11-12 19:29:51 -08002585 public void reportSimUnlocked(int subId) {
2586 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
Jayachandran Cf5436a62019-11-08 18:22:45 -08002587 handleSimStateChange(subId, getSlotId(subId), TelephonyManager.SIM_STATE_READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002588 }
2589
Brian Colonna7fce3802013-09-17 15:51:32 -04002590 /**
2591 * Report that the emergency call button has been pressed and the emergency dialer is
2592 * about to be displayed.
2593 *
2594 * @param bypassHandler runs immediately.
2595 *
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002596 * NOTE: Must be called from UI thread if bypassHandler == true.
Brian Colonna7fce3802013-09-17 15:51:32 -04002597 */
2598 public void reportEmergencyCallAction(boolean bypassHandler) {
2599 if (!bypassHandler) {
2600 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
2601 } else {
Beverly1467c9e2020-02-18 13:31:29 -05002602 Assert.isMainThread();
Brian Colonna7fce3802013-09-17 15:51:32 -04002603 handleReportEmergencyCallAction();
2604 }
2605 }
2606
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002607 /**
2608 * @return Whether the device is provisioned (whether they have gone through
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002609 * the setup wizard)
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002610 */
2611 public boolean isDeviceProvisioned() {
2612 return mDeviceProvisioned;
2613 }
2614
Kensuke Matsui21d1bf12017-03-14 13:27:20 +09002615 public ServiceState getServiceState(int subId) {
2616 return mServiceStates.get(subId);
2617 }
2618
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002619 public void clearBiometricRecognized() {
Beverly1467c9e2020-02-18 13:31:29 -05002620 Assert.isMainThread();
Jim Miller9f0753f2015-03-23 23:59:22 -07002621 mUserFingerprintAuthenticated.clear();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002622 mUserFaceAuthenticated.clear();
2623 mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FINGERPRINT);
2624 mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FACE);
Aran Ink4c0d5602019-06-21 14:27:32 -04002625
2626 for (int i = 0; i < mCallbacks.size(); i++) {
2627 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2628 if (cb != null) {
2629 cb.onBiometricsCleared();
2630 }
2631 }
Jim Millerf41fc962014-06-18 16:33:51 -07002632 }
2633
Jim Miller52a61332014-11-12 19:29:51 -08002634 public boolean isSimPinVoiceSecure() {
2635 // TODO: only count SIMs that handle voice
2636 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07002637 }
2638
Lucas Dupin7156bc72019-05-03 19:37:39 -07002639 /**
2640 * If any SIM cards are currently secure.
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002641 *
Lucas Dupin7156bc72019-05-03 19:37:39 -07002642 * @see #isSimPinSecure(State)
2643 */
Jim Millerdcb3d842012-08-23 19:18:12 -07002644 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08002645 // True if any SIM is pin secure
2646 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
2647 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
2648 }
2649 return false;
2650 }
2651
Jayachandran Cf5436a62019-11-08 18:22:45 -08002652 public int getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08002653 if (mSimDatas.containsKey(subId)) {
2654 return mSimDatas.get(subId).simState;
2655 } else {
Jayachandran Cf5436a62019-11-08 18:22:45 -08002656 return TelephonyManager.SIM_STATE_UNKNOWN;
Jim Miller52a61332014-11-12 19:29:51 -08002657 }
2658 }
2659
Lucas Dupin10960bd2019-09-27 16:08:32 -07002660 private int getSlotId(int subId) {
2661 if (!mSimDatas.containsKey(subId)) {
2662 refreshSimState(subId, SubscriptionManager.getSlotIndex(subId));
2663 }
2664 return mSimDatas.get(subId).slotId;
2665 }
2666
Winson Chung67f5c8b2018-09-24 12:09:19 -07002667 private final TaskStackChangeListener
2668 mTaskStackListener = new TaskStackChangeListener() {
Kevin Chyn2fefd462017-04-28 12:18:19 -07002669 @Override
2670 public void onTaskStackChangedBackground() {
2671 try {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002672 ActivityManager.StackInfo info = ActivityTaskManager.getService().getStackInfo(
Wale Ogunwale68278562017-09-23 17:13:55 -07002673 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
Kevin Chyn2fefd462017-04-28 12:18:19 -07002674 if (info == null) {
2675 return;
2676 }
2677 mHandler.sendMessage(mHandler.obtainMessage(MSG_ASSISTANT_STACK_CHANGED,
2678 info.visible));
2679 } catch (RemoteException e) {
2680 Log.e(TAG, "unable to check task stack", e);
2681 }
2682 }
2683 };
2684
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002685 /**
Richard Choue0381b82018-04-24 03:48:59 +00002686 * @return true if and only if the state has changed for the specified {@code slotId}
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002687 */
Richard Choue0381b82018-04-24 03:48:59 +00002688 private boolean refreshSimState(int subId, int slotId) {
Jayachandran Ca43d0a72019-11-01 17:39:38 -07002689 final TelephonyManager tele =
Raff Tsaif4ea5622019-06-26 16:15:21 +08002690 (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
Jayachandran Cf5436a62019-11-08 18:22:45 -08002691 int state = (tele != null) ?
Raff Tsaif4ea5622019-06-26 16:15:21 +08002692 tele.getSimState(slotId) : TelephonyManager.SIM_STATE_UNKNOWN;
Richard Choue0381b82018-04-24 03:48:59 +00002693 SimData data = mSimDatas.get(subId);
2694 final boolean changed;
2695 if (data == null) {
2696 data = new SimData(state, slotId, subId);
2697 mSimDatas.put(subId, data);
2698 changed = true; // no data yet; force update
2699 } else {
2700 changed = data.simState != state;
2701 data.simState = state;
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002702 }
Richard Choue0381b82018-04-24 03:48:59 +00002703 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07002704 }
2705
Lucas Dupin7156bc72019-05-03 19:37:39 -07002706 /**
2707 * If the {@code state} is currently requiring a SIM PIN, PUK, or is disabled.
2708 */
Jayachandran Cf5436a62019-11-08 18:22:45 -08002709 public static boolean isSimPinSecure(int state) {
2710 return (state == TelephonyManager.SIM_STATE_PIN_REQUIRED
2711 || state == TelephonyManager.SIM_STATE_PUK_REQUIRED
2712 || state == TelephonyManager.SIM_STATE_PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07002713 }
Jim Miller8f09fd22013-03-14 19:04:28 -07002714
2715 public DisplayClientState getCachedDisplayClientState() {
2716 return mDisplayClientState;
2717 }
Jim Miller20daffd2013-10-07 14:59:53 -07002718
2719 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
2720 // (KeyguardViewMediator, KeyguardHostView)
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002721 public void dispatchStartedWakingUp() {
2722 synchronized (this) {
2723 mDeviceInteractive = true;
2724 }
2725 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
2726 }
2727
Jorim Jaggi95e40382015-09-16 15:53:42 -07002728 public void dispatchStartedGoingToSleep(int why) {
2729 mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
2730 }
2731
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002732 public void dispatchFinishedGoingToSleep(int why) {
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002733 synchronized (this) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002734 mDeviceInteractive = false;
2735 }
2736 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
2737 }
2738
Jim Miller20daffd2013-10-07 14:59:53 -07002739 public void dispatchScreenTurnedOn() {
2740 synchronized (this) {
2741 mScreenOn = true;
2742 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07002743 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
Jim Miller20daffd2013-10-07 14:59:53 -07002744 }
2745
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002746 public void dispatchScreenTurnedOff() {
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002747 synchronized (this) {
Jim Miller20daffd2013-10-07 14:59:53 -07002748 mScreenOn = false;
2749 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07002750 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
Jim Miller20daffd2013-10-07 14:59:53 -07002751 }
2752
Selim Cinek99415392016-09-09 14:58:41 -07002753 public void dispatchDreamingStarted() {
2754 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 1, 0));
2755 }
2756
2757 public void dispatchDreamingStopped() {
2758 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 0, 0));
2759 }
2760
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002761 public boolean isDeviceInteractive() {
2762 return mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -07002763 }
Jim Miller52a61332014-11-12 19:29:51 -08002764
Jorim Jaggi95e40382015-09-16 15:53:42 -07002765 public boolean isGoingToSleep() {
2766 return mGoingToSleep;
2767 }
2768
Jim Miller52a61332014-11-12 19:29:51 -08002769 /**
2770 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002771 *
Wink Savilled09c4ca2014-11-22 10:08:16 -08002772 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08002773 */
Jayachandran Cf5436a62019-11-08 18:22:45 -08002774 public int getNextSubIdForState(int state) {
Jim Miller52a61332014-11-12 19:29:51 -08002775 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08002776 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08002777 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
2778 for (int i = 0; i < list.size(); i++) {
2779 final SubscriptionInfo info = list.get(i);
2780 final int id = info.getSubscriptionId();
Lucas Dupin10960bd2019-09-27 16:08:32 -07002781 int slotId = getSlotId(id);
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002782 if (state == getSimState(id) && bestSlotId > slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08002783 resultId = id;
2784 bestSlotId = slotId;
2785 }
2786 }
2787 return resultId;
2788 }
2789
2790 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
2791 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
2792 for (int i = 0; i < list.size(); i++) {
2793 SubscriptionInfo info = list.get(i);
2794 if (subId == info.getSubscriptionId()) return info;
2795 }
2796 return null; // not found
2797 }
Jason Monkab525272015-07-13 17:02:49 -04002798
Alex Chauff7653d2018-02-01 17:18:08 +00002799 /**
2800 * @return a cached version of DevicePolicyManager.isLogoutEnabled()
2801 */
2802 public boolean isLogoutEnabled() {
2803 return mLogoutEnabled;
2804 }
2805
2806 private void updateLogoutEnabled() {
Beverly1467c9e2020-02-18 13:31:29 -05002807 Assert.isMainThread();
Alex Chauff7653d2018-02-01 17:18:08 +00002808 boolean logoutEnabled = mDevicePolicyManager.isLogoutEnabled();
2809 if (mLogoutEnabled != logoutEnabled) {
2810 mLogoutEnabled = logoutEnabled;
Dave Mankoff4b0ab652019-08-07 09:49:20 -04002811
Alex Chauff7653d2018-02-01 17:18:08 +00002812 for (int i = 0; i < mCallbacks.size(); i++) {
2813 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2814 if (cb != null) {
2815 cb.onLogoutEnabledChanged();
2816 }
2817 }
2818 }
2819 }
2820
Beverly4e7dd9a2020-02-28 17:04:21 -05002821 /**
2822 * Unregister all listeners.
2823 */
2824 public void destroy() {
2825 // TODO: inject these dependencies:
2826 TelephonyManager telephony =
2827 (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
2828 if (telephony != null) {
2829 telephony.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
2830 }
2831
2832 mSubscriptionManager.removeOnSubscriptionsChangedListener(mSubscriptionListener);
2833
2834 if (mDeviceProvisionedObserver != null) {
2835 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
2836 }
2837
2838 try {
2839 ActivityManager.getService().unregisterUserSwitchObserver(mUserSwitchObserver);
2840 } catch (RemoteException e) {
2841 Log.d(TAG, "RemoteException onDestroy. cannot unregister userSwitchObserver");
2842 }
2843
2844 ActivityManagerWrapper.getInstance().unregisterTaskStackListener(mTaskStackListener);
2845
2846 mBroadcastDispatcher.unregisterReceiver(mBroadcastReceiver);
2847 mBroadcastDispatcher.unregisterReceiver(mBroadcastAllReceiver);
Fabian Kozynskib6a20372020-04-01 09:36:43 -04002848 mRingerModeTracker.getRingerMode().removeObserver(mRingerModeObserver);
Beverly8947d752020-03-17 08:59:43 -04002849
2850 mHandler.removeCallbacksAndMessages(null);
Beverly4e7dd9a2020-02-28 17:04:21 -05002851 }
2852
Lucas Dupin64171fe2019-10-30 14:28:29 -07002853 @Override
Jason Monkab525272015-07-13 17:02:49 -04002854 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2855 pw.println("KeyguardUpdateMonitor state:");
2856 pw.println(" SIM States:");
2857 for (SimData data : mSimDatas.values()) {
2858 pw.println(" " + data.toString());
2859 }
2860 pw.println(" Subs:");
2861 if (mSubscriptionInfo != null) {
2862 for (int i = 0; i < mSubscriptionInfo.size(); i++) {
2863 pw.println(" " + mSubscriptionInfo.get(i));
2864 }
2865 }
Malcolm Chen5c63b512019-08-13 13:24:07 -07002866 pw.println(" Current active data subId=" + mActiveMobileDataSubscription);
Jason Monkab525272015-07-13 17:02:49 -04002867 pw.println(" Service states:");
2868 for (int subId : mServiceStates.keySet()) {
2869 pw.println(" " + subId + "=" + mServiceStates.get(subId));
2870 }
Jim Millerd72d5ac2015-09-29 18:55:32 -07002871 if (mFpm != null && mFpm.isHardwareDetected()) {
2872 final int userId = ActivityManager.getCurrentUser();
2873 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
Haining Chenc06c4812020-01-13 20:38:53 -08002874 BiometricAuthenticated fingerprint = mUserFingerprintAuthenticated.get(userId);
Jim Millerd72d5ac2015-09-29 18:55:32 -07002875 pw.println(" Fingerprint state (user=" + userId + ")");
Ned Burns017b1bb2020-02-20 20:16:29 -05002876 pw.println(" allowed="
2877 + (fingerprint != null
2878 && isUnlockingWithBiometricAllowed(fingerprint.mIsStrongBiometric)));
2879 pw.println(" auth'd=" + (fingerprint != null && fingerprint.mAuthenticated));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002880 pw.println(" authSinceBoot="
2881 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
2882 pw.println(" disabled(DPM)=" + isFingerprintDisabled(userId));
2883 pw.println(" possible=" + isUnlockWithFingerprintPossible(userId));
Adrian Roos2aaf9442018-11-20 16:57:33 +01002884 pw.println(" listening: actual=" + mFingerprintRunningState
2885 + " expected=" + (shouldListenForFingerprint() ? 1 : 0));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002886 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002887 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
2888 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07002889 if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002890 final int userId = ActivityManager.getCurrentUser();
2891 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
Haining Chenc06c4812020-01-13 20:38:53 -08002892 BiometricAuthenticated face = mUserFaceAuthenticated.get(userId);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002893 pw.println(" Face authentication state (user=" + userId + ")");
Ned Burns017b1bb2020-02-20 20:16:29 -05002894 pw.println(" allowed="
2895 + (face != null && isUnlockingWithBiometricAllowed(face.mIsStrongBiometric)));
2896 pw.println(" auth'd="
2897 + (face != null && face.mAuthenticated));
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002898 pw.println(" authSinceBoot="
2899 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
2900 pw.println(" disabled(DPM)=" + isFaceDisabled(userId));
2901 pw.println(" possible=" + isUnlockWithFacePossible(userId));
2902 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
2903 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
Lucas Dupin7d95f152019-07-17 16:25:54 -07002904 pw.println(" enabledByUser=" + mFaceSettingEnabledForUser.get(userId));
Kevin Chynd0381892019-07-11 16:25:36 -07002905 pw.println(" mSecureCameraLaunched=" + mSecureCameraLaunched);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002906 }
Jason Monkab525272015-07-13 17:02:49 -04002907 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002908}