blob: 45f69d6a2af1d46c381a74696d2c6c3796e07eda [file] [log] [blame]
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jim Miller5ecd8112013-01-09 18:50:26 -080017package com.android.keyguard;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080018
Wale Ogunwale68278562017-09-23 17:13:55 -070019import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
20import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Jorim Jaggidadafd42016-09-30 07:20:25 -070021import static android.content.Intent.ACTION_USER_UNLOCKED;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070022import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
23import static android.os.BatteryManager.BATTERY_STATUS_FULL;
24import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
25import static android.os.BatteryManager.EXTRA_HEALTH;
26import static android.os.BatteryManager.EXTRA_LEVEL;
27import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
28import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
29import static android.os.BatteryManager.EXTRA_PLUGGED;
30import static android.os.BatteryManager.EXTRA_STATUS;
Fabian Kozynskiccde55d2019-06-26 10:06:09 -040031import static android.telephony.PhoneStateListener.LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070032
Adrian Roos30a2ae62018-04-25 19:09:50 +020033import android.annotation.AnyThread;
34import android.annotation.MainThread;
Jorim Jaggiccdfa932015-04-13 16:29:48 -070035import android.app.ActivityManager;
Wale Ogunwale04d9cb52018-04-30 13:55:07 -070036import android.app.ActivityTaskManager;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020037import android.app.AlarmManager;
Adrian Roos30a2ae62018-04-25 19:09:50 +020038import android.app.Instrumentation;
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;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080051import android.database.ContentObserver;
Kevin Chynb7b54a62018-09-28 18:48:12 -070052import android.hardware.biometrics.BiometricManager;
Kevin Chyn56233ab2018-09-20 17:10:57 -070053import android.hardware.biometrics.BiometricSourceType;
Kevin Chynb7b54a62018-09-28 18:48:12 -070054import android.hardware.biometrics.IBiometricEnabledOnKeyguardCallback;
Gilad Brettercb51b8b2018-03-22 17:04:51 +020055import android.hardware.face.FaceManager;
Jorim Jaggi86bed402015-08-20 18:20:02 -070056import android.hardware.fingerprint.FingerprintManager;
57import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
58import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
Jim Miller47088bb2009-11-24 00:40:16 -080059import android.media.AudioManager;
Jim Miller79a444a2011-02-15 15:02:11 -080060import android.os.BatteryManager;
Jim Miller9f0753f2015-03-23 23:59:22 -070061import android.os.CancellationSignal;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080062import android.os.Handler;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070063import android.os.IRemoteCallback;
Jason Monk7bb59302018-05-10 19:38:18 -070064import android.os.Looper;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080065import android.os.Message;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070066import android.os.RemoteException;
Adrian Roosca8a2162017-08-17 19:00:58 +020067import android.os.ServiceManager;
Nick Desaulniers1d396752016-07-25 15:05:33 -070068import android.os.Trace;
Amith Yamasanie8e93a12013-05-09 18:12:30 -070069import android.os.UserHandle;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070070import android.os.UserManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080071import android.provider.Settings;
Kevin Chyn36778ff2017-09-07 19:55:38 -070072import android.service.dreams.DreamService;
73import android.service.dreams.IDreamManager;
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;
Adrian Roos46842d92014-03-27 14:58:03 +010081import android.util.SparseBooleanArray;
82
Lucas Dupin7517b5d2017-08-22 12:51:25 -070083import com.android.internal.annotations.VisibleForTesting;
Jorim Jaggi86bed402015-08-20 18:20:02 -070084import com.android.internal.telephony.IccCardConstants;
85import com.android.internal.telephony.IccCardConstants.State;
86import com.android.internal.telephony.PhoneConstants;
87import com.android.internal.telephony.TelephonyIntents;
Adrian Roos30a2ae62018-04-25 19:09:50 +020088import com.android.internal.util.Preconditions;
Adrian Roosb5e47222015-08-14 15:53:06 -070089import com.android.internal.widget.LockPatternUtils;
Bill Linef81cbd2018-07-05 17:48:49 +080090import com.android.settingslib.WirelessUtils;
Winson Chung2cf6ad82017-11-09 17:36:59 -080091import com.android.systemui.shared.system.ActivityManagerWrapper;
Winson Chung67f5c8b2018-09-24 12:09:19 -070092import com.android.systemui.shared.system.TaskStackChangeListener;
Lucas Dupin9e484aa2019-06-24 13:38:00 -070093import com.android.systemui.statusbar.phone.KeyguardBypassController;
Kevin Chyn1123ba72018-10-26 10:34:06 -070094
Kevin Chyn36778ff2017-09-07 19:55:38 -070095import com.google.android.collect.Lists;
96
Jason Monkab525272015-07-13 17:02:49 -040097import java.io.FileDescriptor;
98import java.io.PrintWriter;
Jim Millerdcb3d842012-08-23 19:18:12 -070099import java.lang.ref.WeakReference;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800100import java.util.ArrayList;
Jim Miller52a61332014-11-12 19:29:51 -0800101import java.util.HashMap;
102import java.util.List;
103import java.util.Map.Entry;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500104import java.util.TimeZone;
Lucas Dupin3d053532019-01-29 12:35:22 -0800105import java.util.function.Consumer;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800106
107/**
108 * Watches for updates that may be interesting to the keyguard, and provides
109 * the up to date information as well as a registration for callbacks that care
110 * to be updated.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800111 */
Adrian Roos46842d92014-03-27 14:58:03 +0100112public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800113
Jim Millerbbf1a742012-07-17 18:30:30 -0700114 private static final String TAG = "KeyguardUpdateMonitor";
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100115 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller52a61332014-11-12 19:29:51 -0800116 private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700117 private static final boolean DEBUG_FACE = true;
Jim Millerbbf1a742012-07-17 18:30:30 -0700118 private static final int LOW_BATTERY_THRESHOLD = 20;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800119
Jorim Jaggie7b12522014-08-06 16:41:21 +0200120 private static final String ACTION_FACE_UNLOCK_STARTED
121 = "com.android.facelock.FACE_UNLOCK_STARTED";
122 private static final String ACTION_FACE_UNLOCK_STOPPED
123 = "com.android.facelock.FACE_UNLOCK_STOPPED";
124
Jim Millerbbf1a742012-07-17 18:30:30 -0700125 // Callback messages
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800126 private static final int MSG_TIME_UPDATE = 301;
127 private static final int MSG_BATTERY_UPDATE = 302;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800128 private static final int MSG_SIM_STATE_CHANGE = 304;
Jim Miller47088bb2009-11-24 00:40:16 -0800129 private static final int MSG_RINGER_MODE_CHANGED = 305;
Jim Millerc23024d2010-02-24 15:37:00 -0800130 private static final int MSG_PHONE_STATE_CHANGED = 306;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700131 private static final int MSG_DEVICE_PROVISIONED = 308;
Jim Miller57375342012-09-09 15:20:31 -0700132 private static final int MSG_DPM_STATE_CHANGED = 309;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500133 private static final int MSG_USER_SWITCHING = 310;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700134 private static final int MSG_KEYGUARD_RESET = 312;
Jim Millerf41fc962014-06-18 16:33:51 -0700135 private static final int MSG_BOOT_COMPLETED = 313;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500136 private static final int MSG_USER_SWITCH_COMPLETE = 314;
Jim Millerf41fc962014-06-18 16:33:51 -0700137 private static final int MSG_USER_INFO_CHANGED = 317;
138 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700139 private static final int MSG_STARTED_WAKING_UP = 319;
140 private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700141 private static final int MSG_STARTED_GOING_TO_SLEEP = 321;
Adrian Roosb6011622014-05-14 15:52:53 +0200142 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700143 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
144 private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
Jason Monk052082c2015-06-11 11:35:23 -0400145 private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
Etan Cohen47051d82015-07-06 16:19:04 -0700146 private static final int MSG_SERVICE_STATE_CHANGE = 330;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700147 private static final int MSG_SCREEN_TURNED_ON = 331;
148 private static final int MSG_SCREEN_TURNED_OFF = 332;
Selim Cinek99415392016-09-09 14:58:41 -0700149 private static final int MSG_DREAMING_STATE_CHANGED = 333;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700150 private static final int MSG_USER_UNLOCKED = 334;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700151 private static final int MSG_ASSISTANT_STACK_CHANGED = 335;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200152 private static final int MSG_BIOMETRIC_AUTHENTICATION_CONTINUE = 336;
Alex Chauff7653d2018-02-01 17:18:08 +0000153 private static final int MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED = 337;
Bill Linef81cbd2018-07-05 17:48:49 +0800154 private static final int MSG_TELEPHONY_CAPABLE = 338;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500155 private static final int MSG_TIMEZONE_UPDATE = 339;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800156
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200157 /** Biometric authentication state: Not listening. */
158 private static final int BIOMETRIC_STATE_STOPPED = 0;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700159
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200160 /** Biometric authentication state: Listening. */
161 private static final int BIOMETRIC_STATE_RUNNING = 1;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700162
163 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200164 * Biometric authentication: Cancelling and waiting for the relevant biometric service to
Jorim Jaggi86bed402015-08-20 18:20:02 -0700165 * send us the confirmation that cancellation has happened.
166 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200167 private static final int BIOMETRIC_STATE_CANCELLING = 2;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700168
169 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200170 * Biometric state: During cancelling we got another request to start listening, so when we
Jorim Jaggi86bed402015-08-20 18:20:02 -0700171 * receive the cancellation done signal, we should start listening again.
172 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200173 private static final int BIOMETRIC_STATE_CANCELLING_RESTARTING = 3;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700174
Lucas Dupin51996bb2019-05-16 17:56:43 -0700175 private static final int BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED = -1;
176 public static final int BIOMETRIC_HELP_FACE_NOT_RECOGNIZED = -2;
177
Adrian Roos0c859ae2015-11-23 16:47:50 -0800178 private static final int DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT = 5000000;
179
Jorim Jaggi031f7952016-09-01 16:39:26 -0700180 private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName(
181 "com.android.settings", "com.android.settings.FallbackHome");
182
Adrian Roosca8a2162017-08-17 19:00:58 +0200183
184 /**
185 * If true, the system is in the half-boot-to-decryption-screen state.
186 * Prudently disable lockscreen.
187 */
188 public static final boolean CORE_APPS_ONLY;
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700189
Adrian Roosca8a2162017-08-17 19:00:58 +0200190 static {
191 try {
192 CORE_APPS_ONLY = IPackageManager.Stub.asInterface(
193 ServiceManager.getService("package")).isOnlyCoreApps();
194 } catch (RemoteException e) {
195 throw e.rethrowFromSystemServer();
196 }
197 }
198
Jim Millerdcb3d842012-08-23 19:18:12 -0700199 private static KeyguardUpdateMonitor sInstance;
200
Jim Millerbbf1a742012-07-17 18:30:30 -0700201 private final Context mContext;
Kevin Chynfdfd2d32019-03-01 14:52:15 -0800202 private final boolean mIsPrimaryUser;
Jim Miller52a61332014-11-12 19:29:51 -0800203 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
Etan Cohen47051d82015-07-06 16:19:04 -0700204 HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700205
Jim Millerbbf1a742012-07-17 18:30:30 -0700206 private int mRingMode;
207 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400208 private boolean mKeyguardIsVisible;
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700209 private boolean mKeyguardGoingAway;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700210 private boolean mGoingToSleep;
Adrian Roosb6011622014-05-14 15:52:53 +0200211 private boolean mBouncer;
Lucas Dupine0516d52019-02-05 17:54:06 -0500212 private boolean mAuthInterruptActive;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800213 private boolean mBootCompleted;
Jorim Jaggi031f7952016-09-01 16:39:26 -0700214 private boolean mNeedsSlowUnlockTransition;
Jorim Jaggid11d1a92016-08-16 16:02:32 -0700215 private boolean mHasLockscreenWallpaper;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700216 private boolean mAssistantVisible;
217 private boolean mKeyguardOccluded;
Kevin Chyn6951d3d2019-06-10 14:07:13 -0700218 private boolean mSecureCameraLaunched;
Bill Linef81cbd2018-07-05 17:48:49 +0800219 @VisibleForTesting
220 protected boolean mTelephonyCapable;
Jim Millerbbf1a742012-07-17 18:30:30 -0700221
Jim Millerdcb3d842012-08-23 19:18:12 -0700222 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700223 private boolean mDeviceProvisioned;
224
Jim Millerdcb3d842012-08-23 19:18:12 -0700225 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700226 private BatteryStatus mBatteryStatus;
227
Lucas Dupin3d053532019-01-29 12:35:22 -0800228 @VisibleForTesting
229 protected StrongAuthTracker mStrongAuthTracker;
Jim Millerbbf1a742012-07-17 18:30:30 -0700230
Jim Miller6212cc02012-09-05 17:35:31 -0700231 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700232 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800233 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700234
Brian Colonnaa5239892013-04-15 11:45:40 -0400235 private boolean mSwitchingUser;
236
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700237 private boolean mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -0700238 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800239 private SubscriptionManager mSubscriptionManager;
240 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700241 private TrustManager mTrustManager;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700242 private UserManager mUserManager;
Lucas Dupin9e484aa2019-06-24 13:38:00 -0700243 private KeyguardBypassController mKeyguardBypassController;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200244 private int mFingerprintRunningState = BIOMETRIC_STATE_STOPPED;
245 private int mFaceRunningState = BIOMETRIC_STATE_STOPPED;
Michal Karpinskic52f8672016-11-18 11:32:45 +0000246 private LockPatternUtils mLockPatternUtils;
Kevin Chyn36778ff2017-09-07 19:55:38 -0700247 private final IDreamManager mDreamManager;
248 private boolean mIsDreaming;
Alex Chauff7653d2018-02-01 17:18:08 +0000249 private final DevicePolicyManager mDevicePolicyManager;
250 private boolean mLogoutEnabled;
Lucas Dupinca88e5f2019-05-14 16:11:08 -0700251 // If the user long pressed the lock icon, disabling face auth for the current session.
252 private boolean mLockIconPressed;
Jim Miller20daffd2013-10-07 14:59:53 -0700253
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700254 /**
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200255 * Short delay before restarting biometric authentication after a successful try
256 * This should be slightly longer than the time between on<biometric>Authenticated
257 * (e.g. onFingerprintAuthenticated) and setKeyguardGoingAway(true).
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700258 */
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200259 private static final int BIOMETRIC_CONTINUE_DELAY_MS = 500;
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700260
Kevin Chyn0c45b072017-04-24 16:27:11 -0700261 // If FP daemon dies, keyguard should retry after a short delay
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200262 private int mHardwareFingerprintUnavailableRetryCount = 0;
263 private int mHardwareFaceUnavailableRetryCount = 0;
Kevin Chyn0c45b072017-04-24 16:27:11 -0700264 private static final int HW_UNAVAILABLE_TIMEOUT = 3000; // ms
265 private static final int HW_UNAVAILABLE_RETRY_MAX = 3;
266
Jason Monk7bb59302018-05-10 19:38:18 -0700267 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700268 @Override
269 public void handleMessage(Message msg) {
270 switch (msg.what) {
271 case MSG_TIME_UPDATE:
272 handleTimeUpdate();
273 break;
Robert Snoeberger9c1074f2018-12-07 17:35:21 -0500274 case MSG_TIMEZONE_UPDATE:
275 handleTimeZoneUpdate((String) msg.obj);
276 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700277 case MSG_BATTERY_UPDATE:
278 handleBatteryUpdate((BatteryStatus) msg.obj);
279 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700280 case MSG_SIM_STATE_CHANGE:
Jim Miller52a61332014-11-12 19:29:51 -0800281 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700282 break;
283 case MSG_RINGER_MODE_CHANGED:
284 handleRingerModeChange(msg.arg1);
285 break;
286 case MSG_PHONE_STATE_CHANGED:
Adrian Roosb6011622014-05-14 15:52:53 +0200287 handlePhoneStateChanged((String) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700288 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700289 case MSG_DEVICE_PROVISIONED:
290 handleDeviceProvisioned();
291 break;
292 case MSG_DPM_STATE_CHANGED:
293 handleDevicePolicyManagerStateChanged();
294 break;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500295 case MSG_USER_SWITCHING:
Adrian Roosb6011622014-05-14 15:52:53 +0200296 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
Chris Wrenf41c61b2012-11-29 15:19:54 -0500297 break;
298 case MSG_USER_SWITCH_COMPLETE:
299 handleUserSwitchComplete(msg.arg1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700300 break;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700301 case MSG_KEYGUARD_RESET:
302 handleKeyguardReset();
303 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200304 case MSG_KEYGUARD_BOUNCER_CHANGED:
305 handleKeyguardBouncerChanged(msg.arg1);
306 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800307 case MSG_BOOT_COMPLETED:
308 handleBootCompleted();
309 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700310 case MSG_USER_INFO_CHANGED:
311 handleUserInfoChanged(msg.arg1);
312 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400313 case MSG_REPORT_EMERGENCY_CALL_ACTION:
314 handleReportEmergencyCallAction();
315 break;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700316 case MSG_STARTED_GOING_TO_SLEEP:
317 handleStartedGoingToSleep(msg.arg1);
318 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700319 case MSG_FINISHED_GOING_TO_SLEEP:
320 handleFinishedGoingToSleep(msg.arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700321 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700322 case MSG_STARTED_WAKING_UP:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700323 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_STARTED_WAKING_UP");
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700324 handleStartedWakingUp();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700325 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -0700326 break;
Jorim Jaggie7b12522014-08-06 16:41:21 +0200327 case MSG_FACE_UNLOCK_STATE_CHANGED:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700328 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_FACE_UNLOCK_STATE_CHANGED");
Adrian Roos4a410172014-08-20 17:41:44 +0200329 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
Nick Desaulniers1d396752016-07-25 15:05:33 -0700330 Trace.endSection();
Jorim Jaggie7b12522014-08-06 16:41:21 +0200331 break;
Jim Miller52a61332014-11-12 19:29:51 -0800332 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
333 handleSimSubscriptionInfoChanged();
334 break;
Jason Monk052082c2015-06-11 11:35:23 -0400335 case MSG_AIRPLANE_MODE_CHANGED:
336 handleAirplaneModeChanged();
337 break;
Etan Cohen47051d82015-07-06 16:19:04 -0700338 case MSG_SERVICE_STATE_CHANGE:
Bonian Chena7e9e8c2019-06-02 23:59:31 +0000339 handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
Etan Cohen47051d82015-07-06 16:19:04 -0700340 break;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700341 case MSG_SCREEN_TURNED_ON:
342 handleScreenTurnedOn();
343 break;
344 case MSG_SCREEN_TURNED_OFF:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700345 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_SCREEN_TURNED_ON");
Jorim Jaggif1518da2015-07-30 11:56:36 -0700346 handleScreenTurnedOff();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700347 Trace.endSection();
Jorim Jaggif1518da2015-07-30 11:56:36 -0700348 break;
Selim Cinek99415392016-09-09 14:58:41 -0700349 case MSG_DREAMING_STATE_CHANGED:
350 handleDreamingStateChanged(msg.arg1);
351 break;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700352 case MSG_USER_UNLOCKED:
353 handleUserUnlocked();
354 break;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700355 case MSG_ASSISTANT_STACK_CHANGED:
Lucas Dupin3d053532019-01-29 12:35:22 -0800356 setAssistantVisible((boolean) msg.obj);
Kevin Chyn2fefd462017-04-28 12:18:19 -0700357 break;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200358 case MSG_BIOMETRIC_AUTHENTICATION_CONTINUE:
359 updateBiometricListeningState();
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700360 break;
Alex Chauff7653d2018-02-01 17:18:08 +0000361 case MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED:
362 updateLogoutEnabled();
363 break;
Bill Linef81cbd2018-07-05 17:48:49 +0800364 case MSG_TELEPHONY_CAPABLE:
Lucas Dupin3d053532019-01-29 12:35:22 -0800365 updateTelephonyCapable((boolean) msg.obj);
Bill Linef81cbd2018-07-05 17:48:49 +0800366 break;
Jason Monk7bb59302018-05-10 19:38:18 -0700367 default:
368 super.handleMessage(msg);
369 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700370 }
371 }
372 };
373
Kevin Chynb7b54a62018-09-28 18:48:12 -0700374 private boolean mFaceSettingEnabledForUser;
375 private BiometricManager mBiometricManager;
376 private IBiometricEnabledOnKeyguardCallback mBiometricEnabledCallback =
377 new IBiometricEnabledOnKeyguardCallback.Stub() {
378 @Override
379 public void onChanged(BiometricSourceType type, boolean enabled) throws RemoteException {
380 if (type == BiometricSourceType.FACE) {
381 mFaceSettingEnabledForUser = enabled;
Kevin Chyn1e043d472019-03-11 14:48:17 -0700382 updateFaceListeningState();
Kevin Chynb7b54a62018-09-28 18:48:12 -0700383 }
384 }
385 };
386
Fabian Kozynskiccde55d2019-06-26 10:06:09 -0400387 private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
388 @Override
389 public void onActiveDataSubscriptionIdChanged(int subId) {
390 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
391 }
392 };
393
Wink Savilled09c4ca2014-11-22 10:08:16 -0800394 private OnSubscriptionsChangedListener mSubscriptionListener =
395 new OnSubscriptionsChangedListener() {
Jim Miller52a61332014-11-12 19:29:51 -0800396 @Override
Wink Savilled09c4ca2014-11-22 10:08:16 -0800397 public void onSubscriptionsChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800398 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
399 }
400 };
401
Adrian Roos46842d92014-03-27 14:58:03 +0100402 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200403 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Jim Miller9f0753f2015-03-23 23:59:22 -0700404 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200405 private SparseBooleanArray mUserFaceAuthenticated = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200406 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100407
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700408 private static int sCurrentUser;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200409 private Runnable mUpdateBiometricListeningState = this::updateBiometricListeningState;
Adrian Roos30a2ae62018-04-25 19:09:50 +0200410 private static boolean sDisableHandlerCheckForTesting;
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700411
412 public synchronized static void setCurrentUser(int currentUser) {
413 sCurrentUser = currentUser;
414 }
415
416 public synchronized static int getCurrentUser() {
417 return sCurrentUser;
418 }
419
Adrian Roos46842d92014-03-27 14:58:03 +0100420 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700421 public void onTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200422 checkIsHandlerThread();
Adrian Roos46842d92014-03-27 14:58:03 +0100423 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200424 for (int i = 0; i < mCallbacks.size(); i++) {
425 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
426 if (cb != null) {
427 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700428 if (enabled && flags != 0) {
429 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200430 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200431 }
432 }
Adrian Roos46842d92014-03-27 14:58:03 +0100433 }
434
Lucas Dupinef886542018-01-03 16:03:07 -0800435 @Override
436 public void onTrustError(CharSequence message) {
437 dispatchErrorMessage(message);
438 }
439
Adrian Roos30a2ae62018-04-25 19:09:50 +0200440 private void handleSimSubscriptionInfoChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800441 if (DEBUG_SIM_STATES) {
442 Log.v(TAG, "onSubscriptionInfoChanged()");
Fabian Kozynskiccde55d2019-06-26 10:06:09 -0400443 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList(false);
Wink Savilled09c4ca2014-11-22 10:08:16 -0800444 if (sil != null) {
445 for (SubscriptionInfo subInfo : sil) {
446 Log.v(TAG, "SubInfo:" + subInfo);
447 }
448 } else {
449 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800450 }
451 }
452 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
453
454 // Hack level over 9000: Because the subscription id is not yet valid when we see the
455 // first update in handleSimStateChange, we need to force refresh all all SIM states
456 // so the subscription id for them is consistent.
Richard Choue0381b82018-04-24 03:48:59 +0000457 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
458 for (int i = 0; i < subscriptionInfos.size(); i++) {
459 SubscriptionInfo info = subscriptionInfos.get(i);
460 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
461 if (changed) {
462 changedSubscriptions.add(info);
463 }
464 }
465 for (int i = 0; i < changedSubscriptions.size(); i++) {
466 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800467 for (int j = 0; j < mCallbacks.size(); j++) {
468 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
469 if (cb != null) {
470 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
471 }
472 }
473 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500474 for (int j = 0; j < mCallbacks.size(); j++) {
475 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
476 if (cb != null) {
477 cb.onRefreshCarrierInfo();
478 }
479 }
Jim Miller52a61332014-11-12 19:29:51 -0800480 }
481
Jason Monk052082c2015-06-11 11:35:23 -0400482 private void handleAirplaneModeChanged() {
483 for (int j = 0; j < mCallbacks.size(); j++) {
484 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
485 if (cb != null) {
486 cb.onRefreshCarrierInfo();
487 }
488 }
489 }
490
Wink Savilled09c4ca2014-11-22 10:08:16 -0800491 /** @return List of SubscriptionInfo records, maybe empty but never null */
Adrian Roos316bf542016-08-23 17:53:07 +0200492 public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800493 List<SubscriptionInfo> sil = mSubscriptionInfo;
494 if (sil == null || forceReload) {
Fabian Kozynskiccde55d2019-06-26 10:06:09 -0400495 sil = mSubscriptionManager.getActiveSubscriptionInfoList(false);
Wink Savilled09c4ca2014-11-22 10:08:16 -0800496 }
497 if (sil == null) {
498 // getActiveSubscriptionInfoList was null callers expect an empty list.
499 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
500 } else {
501 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800502 }
503 return mSubscriptionInfo;
504 }
505
Adrian Roos7861c662014-07-25 15:37:28 +0200506 @Override
507 public void onTrustManagedChanged(boolean managed, int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200508 checkIsHandlerThread();
Adrian Roos7861c662014-07-25 15:37:28 +0200509 mUserTrustIsManaged.put(userId, managed);
510
511 for (int i = 0; i < mCallbacks.size(); i++) {
512 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
513 if (cb != null) {
514 cb.onTrustManagedChanged(userId);
515 }
516 }
517 }
518
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700519 /**
520 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is goingAway
521 * @param goingAway
522 */
523 public void setKeyguardGoingAway(boolean goingAway) {
524 mKeyguardGoingAway = goingAway;
Kevin Chyne22f1342017-09-26 10:03:38 -0700525 updateFingerprintListeningState();
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700526 }
527
Kevin Chyn2fefd462017-04-28 12:18:19 -0700528 /**
529 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is occluded
530 * @param occluded
531 */
532 public void setKeyguardOccluded(boolean occluded) {
533 mKeyguardOccluded = occluded;
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200534 updateBiometricListeningState();
Kevin Chyn2fefd462017-04-28 12:18:19 -0700535 }
536
Kevin Chyn36778ff2017-09-07 19:55:38 -0700537 /**
Kevin Chyn6951d3d2019-06-10 14:07:13 -0700538 * Invoked when the secure camera is launched.
539 */
540 public void onCameraLaunched() {
541 mSecureCameraLaunched = true;
542 updateBiometricListeningState();
543 }
544
545 /**
Kevin Chyn36778ff2017-09-07 19:55:38 -0700546 * @return a cached version of DreamManager.isDreaming()
547 */
548 public boolean isDreaming() {
549 return mIsDreaming;
550 }
551
552 /**
553 * If the device is dreaming, awakens the device
554 */
555 public void awakenFromDream() {
556 if (mIsDreaming && mDreamManager != null) {
557 try {
558 mDreamManager.awaken();
559 } catch (RemoteException e) {
560 Log.e(TAG, "Unable to awaken from dream");
561 }
562 }
563 }
564
Lucas Dupin3d053532019-01-29 12:35:22 -0800565 @VisibleForTesting
566 protected void onFingerprintAuthenticated(int userId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700567 Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
Jim Miller9f0753f2015-03-23 23:59:22 -0700568 mUserFingerprintAuthenticated.put(userId, true);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700569 // Update/refresh trust state only if user can skip bouncer
570 if (getUserCanSkipBouncer(userId)) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200571 mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FINGERPRINT);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700572 }
Kevin Chyn625a0142017-04-10 14:53:59 -0700573 // Don't send cancel if authentication succeeds
574 mFingerprintCancelSignal = null;
Jim Millerf41fc962014-06-18 16:33:51 -0700575 for (int i = 0; i < mCallbacks.size(); i++) {
576 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
577 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200578 cb.onBiometricAuthenticated(userId, BiometricSourceType.FINGERPRINT);
Jim Millerf41fc962014-06-18 16:33:51 -0700579 }
580 }
Kevin Chyn2fefd462017-04-28 12:18:19 -0700581
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200582 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE),
583 BIOMETRIC_CONTINUE_DELAY_MS);
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700584
Kevin Chyn2fefd462017-04-28 12:18:19 -0700585 // Only authenticate fingerprint once when assistant is visible
586 mAssistantVisible = false;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700587
Nick Desaulniers1d396752016-07-25 15:05:33 -0700588 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700589 }
590
Jim Millerce7eb6d2015-04-03 19:29:13 -0700591 private void handleFingerprintAuthFailed() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700592 for (int i = 0; i < mCallbacks.size(); i++) {
593 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
594 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200595 cb.onBiometricAuthFailed(BiometricSourceType.FINGERPRINT);
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700596 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700597 }
Lucas Dupin51996bb2019-05-16 17:56:43 -0700598 handleFingerprintHelp(BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED,
599 mContext.getString(R.string.kg_fingerprint_not_recognized));
Jim Millerce7eb6d2015-04-03 19:29:13 -0700600 }
Jim Millerf41fc962014-06-18 16:33:51 -0700601
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700602 private void handleFingerprintAcquired(int acquireInfo) {
603 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
604 return;
605 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700606 for (int i = 0; i < mCallbacks.size(); i++) {
607 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
608 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200609 cb.onBiometricAcquired(BiometricSourceType.FINGERPRINT);
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700610 }
611 }
612 }
613
Jim Miller837fa7e2016-08-08 20:16:22 -0700614 private void handleFingerprintAuthenticated(int authUserId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700615 Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
Jim Millerf41fc962014-06-18 16:33:51 -0700616 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700617 final int userId;
618 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800619 userId = ActivityManager.getService().getCurrentUser().id;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700620 } catch (RemoteException e) {
621 Log.e(TAG, "Failed to get current user id: ", e);
622 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700623 }
Jim Miller837fa7e2016-08-08 20:16:22 -0700624 if (userId != authUserId) {
625 Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId);
626 return;
627 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700628 if (isFingerprintDisabled(userId)) {
629 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
630 return;
631 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700632 onFingerprintAuthenticated(userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700633 } finally {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200634 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Jim Millerf41fc962014-06-18 16:33:51 -0700635 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700636 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700637 }
638
Jim Miller9f0753f2015-03-23 23:59:22 -0700639 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700640 for (int i = 0; i < mCallbacks.size(); i++) {
641 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
642 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200643 cb.onBiometricHelp(msgId, helpString, BiometricSourceType.FINGERPRINT);
Jim Miller9f0753f2015-03-23 23:59:22 -0700644 }
645 }
646 }
647
Kevin Chyn0c45b072017-04-24 16:27:11 -0700648 private Runnable mRetryFingerprintAuthentication = new Runnable() {
649 @Override
650 public void run() {
651 Log.w(TAG, "Retrying fingerprint after HW unavailable, attempt " +
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200652 mHardwareFingerprintUnavailableRetryCount);
Kevin Chyn0c45b072017-04-24 16:27:11 -0700653 updateFingerprintListeningState();
654 }
655 };
656
Jim Miller9f0753f2015-03-23 23:59:22 -0700657 private void handleFingerprintError(int msgId, String errString) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700658 if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200659 && mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
660 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Kevin Chyn1123ba72018-10-26 10:34:06 -0700661 updateFingerprintListeningState();
Jorim Jaggi86bed402015-08-20 18:20:02 -0700662 } else {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200663 setFingerprintRunningState(BIOMETRIC_STATE_STOPPED);
Jorim Jaggi86bed402015-08-20 18:20:02 -0700664 }
Kevin Chyn0c45b072017-04-24 16:27:11 -0700665
666 if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200667 if (mHardwareFingerprintUnavailableRetryCount < HW_UNAVAILABLE_RETRY_MAX) {
668 mHardwareFingerprintUnavailableRetryCount++;
Kevin Chyn0c45b072017-04-24 16:27:11 -0700669 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
670 mHandler.postDelayed(mRetryFingerprintAuthentication, HW_UNAVAILABLE_TIMEOUT);
671 }
672 }
673
Kevin Chyndf9d33e2017-05-03 21:40:12 -0700674 if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
675 mLockPatternUtils.requireStrongAuth(
676 LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
677 getCurrentUser());
678 }
679
Jim Miller9f0753f2015-03-23 23:59:22 -0700680 for (int i = 0; i < mCallbacks.size(); i++) {
681 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
682 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200683 cb.onBiometricError(msgId, errString, BiometricSourceType.FINGERPRINT);
Jim Millerf41fc962014-06-18 16:33:51 -0700684 }
685 }
686 }
687
Jorim Jaggi3a464782015-08-28 16:59:13 -0700688 private void handleFingerprintLockoutReset() {
689 updateFingerprintListeningState();
690 }
691
Jorim Jaggi86bed402015-08-20 18:20:02 -0700692 private void setFingerprintRunningState(int fingerprintRunningState) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200693 boolean wasRunning = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
694 boolean isRunning = fingerprintRunningState == BIOMETRIC_STATE_RUNNING;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700695 mFingerprintRunningState = fingerprintRunningState;
Kevin Chynb4514d22019-04-15 13:47:25 -0700696 Log.d(TAG, "fingerprintRunningState: " + mFingerprintRunningState);
Jorim Jaggi86bed402015-08-20 18:20:02 -0700697 // Clients of KeyguardUpdateMonitor don't care about the internal state about the
Kevin Chynb4514d22019-04-15 13:47:25 -0700698 // asynchronousness of the cancel cycle. So only notify them if the actually running state
Jorim Jaggi86bed402015-08-20 18:20:02 -0700699 // has changed.
700 if (wasRunning != isRunning) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700701 notifyFingerprintRunningStateChanged();
702 }
703 }
704
705 private void notifyFingerprintRunningStateChanged() {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200706 checkIsHandlerThread();
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700707 for (int i = 0; i < mCallbacks.size(); i++) {
708 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
709 if (cb != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200710 cb.onBiometricRunningStateChanged(isFingerprintDetectionRunning(),
711 BiometricSourceType.FINGERPRINT);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700712 }
713 }
714 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200715
Lucas Dupin3d053532019-01-29 12:35:22 -0800716 @VisibleForTesting
717 protected void onFaceAuthenticated(int userId) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200718 Trace.beginSection("KeyGuardUpdateMonitor#onFaceAuthenticated");
719 mUserFaceAuthenticated.put(userId, true);
720 // Update/refresh trust state only if user can skip bouncer
721 if (getUserCanSkipBouncer(userId)) {
722 mTrustManager.unlockedByBiometricForUser(userId, BiometricSourceType.FACE);
723 }
724 // Don't send cancel if authentication succeeds
725 mFaceCancelSignal = null;
726 for (int i = 0; i < mCallbacks.size(); i++) {
727 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
728 if (cb != null) {
729 cb.onBiometricAuthenticated(userId,
730 BiometricSourceType.FACE);
731 }
732 }
733
734 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE),
735 BIOMETRIC_CONTINUE_DELAY_MS);
736
737 // Only authenticate face once when assistant is visible
738 mAssistantVisible = false;
739
740 Trace.endSection();
741 }
742
743 private void handleFaceAuthFailed() {
Lucas Dupin38314812019-02-15 14:10:55 -0800744 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200745 for (int i = 0; i < mCallbacks.size(); i++) {
746 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
747 if (cb != null) {
748 cb.onBiometricAuthFailed(BiometricSourceType.FACE);
749 }
750 }
Lucas Dupin51996bb2019-05-16 17:56:43 -0700751 handleFaceHelp(BIOMETRIC_HELP_FACE_NOT_RECOGNIZED,
752 mContext.getString(R.string.kg_face_not_recognized));
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200753 }
754
755 private void handleFaceAcquired(int acquireInfo) {
756 if (acquireInfo != FaceManager.FACE_ACQUIRED_GOOD) {
757 return;
758 }
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700759 if (DEBUG_FACE) Log.d(TAG, "Face acquired");
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200760 for (int i = 0; i < mCallbacks.size(); i++) {
761 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
762 if (cb != null) {
763 cb.onBiometricAcquired(BiometricSourceType.FACE);
764 }
765 }
766 }
767
768 private void handleFaceAuthenticated(int authUserId) {
769 Trace.beginSection("KeyGuardUpdateMonitor#handlerFaceAuthenticated");
770 try {
Lucas Dupin9bae9c22019-06-04 16:37:40 -0700771 if (mGoingToSleep) {
772 Log.d(TAG, "Aborted successful auth because device is going to sleep.");
773 return;
774 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200775 final int userId;
776 try {
777 userId = ActivityManager.getService().getCurrentUser().id;
778 } catch (RemoteException e) {
779 Log.e(TAG, "Failed to get current user id: ", e);
780 return;
781 }
782 if (userId != authUserId) {
783 Log.d(TAG, "Face authenticated for wrong user: " + authUserId);
784 return;
785 }
786 if (isFaceDisabled(userId)) {
787 Log.d(TAG, "Face authentication disabled by DPM for userId: " + userId);
788 return;
789 }
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700790 if (DEBUG_FACE) Log.d(TAG, "Face auth succeeded for user " + userId);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200791 onFaceAuthenticated(userId);
792 } finally {
793 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
794 }
795 Trace.endSection();
796 }
797
798 private void handleFaceHelp(int msgId, String helpString) {
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700799 if (DEBUG_FACE) Log.d(TAG, "Face help received: " + helpString);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200800 for (int i = 0; i < mCallbacks.size(); i++) {
801 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
802 if (cb != null) {
803 cb.onBiometricHelp(msgId, helpString, BiometricSourceType.FACE);
804 }
805 }
806 }
807
808 private Runnable mRetryFaceAuthentication = new Runnable() {
809 @Override
810 public void run() {
811 Log.w(TAG, "Retrying face after HW unavailable, attempt " +
812 mHardwareFaceUnavailableRetryCount);
813 updateFaceListeningState();
814 }
815 };
816
817 private void handleFaceError(int msgId, String errString) {
Lucas Dupin71d2fb22019-05-30 18:26:54 -0700818 if (DEBUG_FACE) Log.d(TAG, "Face error received: " + errString);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200819 if (msgId == FaceManager.FACE_ERROR_CANCELED
820 && mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
821 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
Kevin Chyn1123ba72018-10-26 10:34:06 -0700822 updateFaceListeningState();
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200823 } else {
824 setFaceRunningState(BIOMETRIC_STATE_STOPPED);
825 }
826
827 if (msgId == FaceManager.FACE_ERROR_HW_UNAVAILABLE) {
828 if (mHardwareFaceUnavailableRetryCount < HW_UNAVAILABLE_RETRY_MAX) {
829 mHardwareFaceUnavailableRetryCount++;
830 mHandler.removeCallbacks(mRetryFaceAuthentication);
831 mHandler.postDelayed(mRetryFaceAuthentication, HW_UNAVAILABLE_TIMEOUT);
832 }
833 }
834
835 if (msgId == FaceManager.FACE_ERROR_LOCKOUT_PERMANENT) {
836 mLockPatternUtils.requireStrongAuth(
837 LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
838 getCurrentUser());
839 }
840
Lucas Dupin51996bb2019-05-16 17:56:43 -0700841 // The face timeout message is not very actionable, let's ask the user to
842 // manually retry.
843 if (msgId == FaceManager.FACE_ERROR_TIMEOUT) {
844 errString = mContext.getString(R.string.keyguard_unlock);
845 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200846 for (int i = 0; i < mCallbacks.size(); i++) {
847 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
848 if (cb != null) {
849 cb.onBiometricError(msgId, errString,
850 BiometricSourceType.FACE);
851 }
852 }
853 }
854
855 private void handleFaceLockoutReset() {
856 updateFaceListeningState();
857 }
858
859 private void setFaceRunningState(int faceRunningState) {
860 boolean wasRunning = mFaceRunningState == BIOMETRIC_STATE_RUNNING;
861 boolean isRunning = faceRunningState == BIOMETRIC_STATE_RUNNING;
862 mFaceRunningState = faceRunningState;
Kevin Chynb4514d22019-04-15 13:47:25 -0700863 Log.d(TAG, "faceRunningState: " + mFaceRunningState);
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200864 // Clients of KeyguardUpdateMonitor don't care about the internal state or about the
Kevin Chynb4514d22019-04-15 13:47:25 -0700865 // asynchronousness of the cancel cycle. So only notify them if the actually running state
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200866 // has changed.
867 if (wasRunning != isRunning) {
868 notifyFaceRunningStateChanged();
869 }
870 }
871
872 private void notifyFaceRunningStateChanged() {
873 for (int i = 0; i < mCallbacks.size(); i++) {
874 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
875 if (cb != null) {
876 cb.onBiometricRunningStateChanged(isFaceDetectionRunning(),
877 BiometricSourceType.FACE);
878 }
879 }
880 }
881
Adrian Roos4a410172014-08-20 17:41:44 +0200882 private void handleFaceUnlockStateChanged(boolean running, int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200883 checkIsHandlerThread();
Adrian Roos4a410172014-08-20 17:41:44 +0200884 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200885 for (int i = 0; i < mCallbacks.size(); i++) {
886 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
887 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200888 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200889 }
890 }
891 }
892
Adrian Roos4a410172014-08-20 17:41:44 +0200893 public boolean isFaceUnlockRunning(int userId) {
894 return mUserFaceUnlockRunning.get(userId);
895 }
896
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700897 public boolean isFingerprintDetectionRunning() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200898 return mFingerprintRunningState == BIOMETRIC_STATE_RUNNING;
899 }
900
901 public boolean isFaceDetectionRunning() {
902 return mFaceRunningState == BIOMETRIC_STATE_RUNNING;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700903 }
904
Jim Miller50e62182014-04-23 17:25:00 -0700905 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100906 // Don't allow trust agent if device is secured with a SIM PIN. This is here
907 // mainly because there's no other way to prompt the user to enter their SIM PIN
908 // once they get past the keyguard screen.
909 final boolean disabledBySimPin = isSimPinSecure();
910 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700911 }
912
Jim Miller06e34502014-07-17 14:46:05 -0700913 private boolean isFingerprintDisabled(int userId) {
914 final DevicePolicyManager dpm =
915 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
916 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
Adrian Roos733b6632015-08-21 14:32:35 -0700917 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0
918 || isSimPinSecure();
Jim Miller06e34502014-07-17 14:46:05 -0700919 }
920
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200921 private boolean isFaceDisabled(int userId) {
922 final DevicePolicyManager dpm =
923 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
924 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
925 & DevicePolicyManager.KEYGUARD_DISABLE_FACE) != 0
926 || isSimPinSecure();
927 }
928
929
Selim Cineke8bae622015-07-15 13:24:06 -0700930 public boolean getUserCanSkipBouncer(int userId) {
Steven Wucfe398d2019-03-21 11:32:15 -0400931 return getUserHasTrust(userId) || getUserUnlockedWithBiometric(userId);
Selim Cineke8bae622015-07-15 13:24:06 -0700932 }
933
Adrian Roos46842d92014-03-27 14:58:03 +0100934 public boolean getUserHasTrust(int userId) {
Selim Cineke8bae622015-07-15 13:24:06 -0700935 return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100936 }
937
Steven Wucfe398d2019-03-21 11:32:15 -0400938 /**
939 * Returns whether the user is unlocked with biometrics.
940 */
941 public boolean getUserUnlockedWithBiometric(int userId) {
942 boolean fingerprintOrFace = mUserFingerprintAuthenticated.get(userId)
943 || mUserFaceAuthenticated.get(userId);
944 return fingerprintOrFace && isUnlockingWithBiometricAllowed();
945 }
946
Adrian Roos7861c662014-07-25 15:37:28 +0200947 public boolean getUserTrustIsManaged(int userId) {
948 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
949 }
950
Gilad Brettercb51b8b2018-03-22 17:04:51 +0200951 public boolean isUnlockingWithBiometricAllowed() {
952 return mStrongAuthTracker.isUnlockingWithBiometricAllowed();
Adrian Roosb5e47222015-08-14 15:53:06 -0700953 }
954
Lucas Dupin16013822018-05-17 18:00:16 -0700955 public boolean isUserInLockdown(int userId) {
956 return mStrongAuthTracker.getStrongAuthForUser(userId)
957 == LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
958 }
959
Lucas Dupin7825b942019-06-03 20:22:39 -0700960 public boolean userNeedsStrongAuth() {
961 return mStrongAuthTracker.getStrongAuthForUser(getCurrentUser())
962 != LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED;
963 }
964
Jorim Jaggi031f7952016-09-01 16:39:26 -0700965 public boolean needsSlowUnlockTransition() {
966 return mNeedsSlowUnlockTransition;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700967 }
968
Adrian Roosb5e47222015-08-14 15:53:06 -0700969 public StrongAuthTracker getStrongAuthTracker() {
970 return mStrongAuthTracker;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700971 }
972
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700973 private void notifyStrongAuthStateChanged(int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200974 checkIsHandlerThread();
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700975 for (int i = 0; i < mCallbacks.size(); i++) {
976 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
977 if (cb != null) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700978 cb.onStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700979 }
980 }
Selim Cinek1fcafc42015-07-20 14:39:25 -0700981 }
982
Adrian Roos91ba3072017-02-14 16:50:46 +0100983 public boolean isScreenOn() {
984 return mScreenOn;
985 }
986
Lucas Dupinef886542018-01-03 16:03:07 -0800987 private void dispatchErrorMessage(CharSequence message) {
988 for (int i = 0; i < mCallbacks.size(); i++) {
989 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
990 if (cb != null) {
991 cb.onTrustAgentErrorMessage(message);
992 }
993 }
994 }
995
Lucas Dupin3d053532019-01-29 12:35:22 -0800996 @VisibleForTesting
997 void setAssistantVisible(boolean assistantVisible) {
998 mAssistantVisible = assistantVisible;
999 updateBiometricListeningState();
1000 }
1001
Jim Miller8f09fd22013-03-14 19:04:28 -07001002 static class DisplayClientState {
1003 public int clientGeneration;
1004 public boolean clearing;
1005 public PendingIntent intent;
1006 public int playbackState;
1007 public long playbackEventTime;
1008 }
1009
1010 private DisplayClientState mDisplayClientState = new DisplayClientState();
1011
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001012 @VisibleForTesting
Lucas Dupin7ff82b02018-05-16 12:14:10 -07001013 protected final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001014
Jim Millerd72d5ac2015-09-29 18:55:32 -07001015 @Override
Jim Millerbbf1a742012-07-17 18:30:30 -07001016 public void onReceive(Context context, Intent intent) {
1017 final String action = intent.getAction();
1018 if (DEBUG) Log.d(TAG, "received broadcast " + action);
1019
1020 if (Intent.ACTION_TIME_TICK.equals(action)
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05001021 || Intent.ACTION_TIME_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -07001022 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05001023 } else if (Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
1024 final Message msg = mHandler.obtainMessage(
1025 MSG_TIMEZONE_UPDATE, intent.getStringExtra("time-zone"));
1026 mHandler.sendMessage(msg);
Jim Millerbbf1a742012-07-17 18:30:30 -07001027 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
1028 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
1029 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
1030 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
1031 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
Adrian Roos0c859ae2015-11-23 16:47:50 -08001032
1033 final int maxChargingMicroAmp = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
1034 int maxChargingMicroVolt = intent.getIntExtra(EXTRA_MAX_CHARGING_VOLTAGE, -1);
1035 final int maxChargingMicroWatt;
1036
1037 if (maxChargingMicroVolt <= 0) {
1038 maxChargingMicroVolt = DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT;
1039 }
1040 if (maxChargingMicroAmp > 0) {
1041 // Calculating muW = muA * muV / (10^6 mu^2 / mu); splitting up the divisor
1042 // to maintain precision equally on both factors.
1043 maxChargingMicroWatt = (maxChargingMicroAmp / 1000)
1044 * (maxChargingMicroVolt / 1000);
1045 } else {
1046 maxChargingMicroWatt = -1;
1047 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001048 final Message msg = mHandler.obtainMessage(
Adrian Roos7b043112015-07-10 13:00:33 -07001049 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
Adrian Roos0c859ae2015-11-23 16:47:50 -08001050 maxChargingMicroWatt));
Jim Millerbbf1a742012-07-17 18:30:30 -07001051 mHandler.sendMessage(msg);
1052 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Bill Linef81cbd2018-07-05 17:48:49 +08001053 SimData args = SimData.fromIntent(intent);
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001054 // ACTION_SIM_STATE_CHANGED is rebroadcast after unlocking the device to
1055 // keep compatibility with apps that aren't direct boot aware.
1056 // SysUI should just ignore this broadcast because it was already received
1057 // and processed previously.
1058 if (intent.getBooleanExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
Bill Linef81cbd2018-07-05 17:48:49 +08001059 // Guarantee mTelephonyCapable state after SysUI crash and restart
1060 if (args.simState == State.ABSENT) {
1061 mHandler.obtainMessage(MSG_TELEPHONY_CAPABLE, true).sendToTarget();
1062 }
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001063 return;
1064 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001065 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -08001066 Log.v(TAG, "action " + action
1067 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
1068 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -07001069 }
Jim Miller52a61332014-11-12 19:29:51 -08001070 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
1071 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -07001072 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
1073 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
1074 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
1075 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
1076 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
1077 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Jason Monk052082c2015-06-11 11:35:23 -04001078 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
1079 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001080 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -07001081 dispatchBootCompleted();
Etan Cohen47051d82015-07-06 16:19:04 -07001082 } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
1083 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
1084 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
1085 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
1086 if (DEBUG) {
1087 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
1088 + subId);
1089 }
Bonian Chena7e9e8c2019-06-02 23:59:31 +00001090 mHandler.sendMessage(
1091 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
Fabian Kozynskiccde55d2019-06-26 10:06:09 -04001092 } else if (TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED.equals(action)) {
1093 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
Alex Chauff7653d2018-02-01 17:18:08 +00001094 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
1095 action)) {
1096 mHandler.sendEmptyMessage(MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001097 }
1098 }
1099 };
Jim Miller2de5ee82012-06-14 22:22:50 -07001100
Lucas Dupin3d053532019-01-29 12:35:22 -08001101 @VisibleForTesting
1102 protected final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001103
Jim Millerd72d5ac2015-09-29 18:55:32 -07001104 @Override
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001105 public void onReceive(Context context, Intent intent) {
1106 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +02001107 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
1108 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
1109 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001110 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
1111 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +02001112 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001113 Trace.beginSection("KeyguardUpdateMonitor.mBroadcastAllReceiver#onReceive ACTION_FACE_UNLOCK_STARTED");
Adrian Roos48c796c2014-09-01 14:59:23 +02001114 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
1115 getSendingUserId()));
Nick Desaulniers1d396752016-07-25 15:05:33 -07001116 Trace.endSection();
Adrian Roos48c796c2014-09-01 14:59:23 +02001117 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
1118 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
1119 getSendingUserId()));
1120 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
1121 .equals(action)) {
1122 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001123 } else if (ACTION_USER_UNLOCKED.equals(action)) {
1124 mHandler.sendEmptyMessage(MSG_USER_UNLOCKED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001125 }
1126 }
1127 };
Jim Miller9f0753f2015-03-23 23:59:22 -07001128
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001129 private final FingerprintManager.LockoutResetCallback mFingerprintLockoutResetCallback
Jorim Jaggi3a464782015-08-28 16:59:13 -07001130 = new FingerprintManager.LockoutResetCallback() {
1131 @Override
1132 public void onLockoutReset() {
1133 handleFingerprintLockoutReset();
1134 }
1135 };
1136
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001137 private final FaceManager.LockoutResetCallback mFaceLockoutResetCallback
1138 = new FaceManager.LockoutResetCallback() {
1139 @Override
1140 public void onLockoutReset() {
1141 handleFaceLockoutReset();
1142 }
1143 };
1144
1145 private FingerprintManager.AuthenticationCallback mFingerprintAuthenticationCallback
Jim Miller9f0753f2015-03-23 23:59:22 -07001146 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -07001147
1148 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -07001149 public void onAuthenticationFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001150 handleFingerprintAuthFailed();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001151 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001152
1153 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -07001154 public void onAuthenticationSucceeded(AuthenticationResult result) {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001155 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
Jim Miller837fa7e2016-08-08 20:16:22 -07001156 handleFingerprintAuthenticated(result.getUserId());
Nick Desaulniers1d396752016-07-25 15:05:33 -07001157 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -07001158 }
1159
1160 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -07001161 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001162 handleFingerprintHelp(helpMsgId, helpString.toString());
Jim Miller9f0753f2015-03-23 23:59:22 -07001163 }
1164
1165 @Override
1166 public void onAuthenticationError(int errMsgId, CharSequence errString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -07001167 handleFingerprintError(errMsgId, errString.toString());
1168 }
1169
1170 @Override
1171 public void onAuthenticationAcquired(int acquireInfo) {
1172 handleFingerprintAcquired(acquireInfo);
Jim Millerf41fc962014-06-18 16:33:51 -07001173 }
1174 };
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001175
Lucas Dupin3d053532019-01-29 12:35:22 -08001176 @VisibleForTesting
1177 FaceManager.AuthenticationCallback mFaceAuthenticationCallback
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001178 = new FaceManager.AuthenticationCallback() {
1179
1180 @Override
1181 public void onAuthenticationFailed() {
1182 handleFaceAuthFailed();
1183 }
1184
1185 @Override
1186 public void onAuthenticationSucceeded(FaceManager.AuthenticationResult result) {
1187 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
1188 handleFaceAuthenticated(result.getUserId());
1189 Trace.endSection();
1190 }
1191
1192 @Override
1193 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
1194 handleFaceHelp(helpMsgId, helpString.toString());
1195 }
1196
1197 @Override
1198 public void onAuthenticationError(int errMsgId, CharSequence errString) {
1199 handleFaceError(errMsgId, errString.toString());
1200 }
1201
1202 @Override
1203 public void onAuthenticationAcquired(int acquireInfo) {
1204 handleFaceAcquired(acquireInfo);
1205 }
1206 };
1207
Jim Miller9f0753f2015-03-23 23:59:22 -07001208 private CancellationSignal mFingerprintCancelSignal;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001209 private CancellationSignal mFaceCancelSignal;
Jim Miller9f0753f2015-03-23 23:59:22 -07001210 private FingerprintManager mFpm;
Kevin Chynb7b54a62018-09-28 18:48:12 -07001211 private FaceManager mFaceManager;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001212
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001213 /**
Jim Miller47088bb2009-11-24 00:40:16 -08001214 * When we receive a
1215 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -07001216 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001217 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -08001218 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001219 */
Jim Miller52a61332014-11-12 19:29:51 -08001220 private static class SimData {
1221 public State simState;
1222 public int slotId;
1223 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001224
Jim Miller52a61332014-11-12 19:29:51 -08001225 SimData(State state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -08001226 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -08001227 slotId = slot;
1228 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -08001229 }
1230
Jim Miller52a61332014-11-12 19:29:51 -08001231 static SimData fromIntent(Intent intent) {
1232 State state;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001233 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
1234 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
1235 }
Wink Savillea639b312012-07-10 12:37:54 -07001236 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
Jayachandran Cbd481352019-05-21 16:02:23 -07001237 int slotId = intent.getIntExtra(PhoneConstants.PHONE_KEY, 0);
Jim Miller52a61332014-11-12 19:29:51 -08001238 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
Wink Savilled09c4ca2014-11-22 10:08:16 -08001239 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea639b312012-07-10 12:37:54 -07001240 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -07001241 final String absentReason = intent
Wink Savillea639b312012-07-10 12:37:54 -07001242 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -07001243
Wink Savillea639b312012-07-10 12:37:54 -07001244 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -07001245 absentReason)) {
Wink Savillea639b312012-07-10 12:37:54 -07001246 state = IccCardConstants.State.PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -07001247 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001248 state = IccCardConstants.State.ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -07001249 }
Wink Savillea639b312012-07-10 12:37:54 -07001250 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
1251 state = IccCardConstants.State.READY;
1252 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001253 final String lockedReason = intent
Wink Savillea639b312012-07-10 12:37:54 -07001254 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
1255 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
1256 state = IccCardConstants.State.PIN_REQUIRED;
1257 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
1258 state = IccCardConstants.State.PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001259 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001260 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001261 }
Wink Savillea639b312012-07-10 12:37:54 -07001262 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
1263 state = IccCardConstants.State.NETWORK_LOCKED;
Wileen Chiu6b8b22e2014-10-29 22:48:21 +05301264 } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
1265 state = IccCardConstants.State.CARD_IO_ERROR;
Jim Miller109f1fd2012-09-19 20:44:16 -07001266 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
1267 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
1268 // This is required because telephony doesn't return to "READY" after
1269 // these state transitions. See bug 7197471.
1270 state = IccCardConstants.State.READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001271 } else {
Wink Savillea639b312012-07-10 12:37:54 -07001272 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001273 }
Jim Miller52a61332014-11-12 19:29:51 -08001274 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001275 }
1276
Jim Millerd72d5ac2015-09-29 18:55:32 -07001277 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001278 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -08001279 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001280 }
1281 }
1282
Adrian Roos12c1ef52014-06-04 13:54:08 +02001283 public static class BatteryStatus {
Adrian Roos7b043112015-07-10 13:00:33 -07001284 public static final int CHARGING_UNKNOWN = -1;
1285 public static final int CHARGING_SLOWLY = 0;
1286 public static final int CHARGING_REGULAR = 1;
1287 public static final int CHARGING_FAST = 2;
1288
Jim Miller16464b82011-10-20 21:10:13 -07001289 public final int status;
1290 public final int level;
1291 public final int plugged;
1292 public final int health;
Adrian Roos0c859ae2015-11-23 16:47:50 -08001293 public final int maxChargingWattage;
1294 public BatteryStatus(int status, int level, int plugged, int health,
1295 int maxChargingWattage) {
Jim Miller16464b82011-10-20 21:10:13 -07001296 this.status = status;
1297 this.level = level;
1298 this.plugged = plugged;
1299 this.health = health;
Adrian Roos0c859ae2015-11-23 16:47:50 -08001300 this.maxChargingWattage = maxChargingWattage;
Jim Miller16464b82011-10-20 21:10:13 -07001301 }
1302
Jim Millerbbf1a742012-07-17 18:30:30 -07001303 /**
Brian Muramatsua92a01b2012-09-05 21:54:39 -07001304 * Determine whether the device is plugged in (USB, power, or wireless).
Jim Millerbbf1a742012-07-17 18:30:30 -07001305 * @return true if the device is plugged in.
1306 */
Adrian Roosad3bc7f2014-10-30 18:29:38 +01001307 public boolean isPluggedIn() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001308 return plugged == BatteryManager.BATTERY_PLUGGED_AC
Brian Muramatsua92a01b2012-09-05 21:54:39 -07001309 || plugged == BatteryManager.BATTERY_PLUGGED_USB
1310 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Jim Millerbbf1a742012-07-17 18:30:30 -07001311 }
1312
1313 /**
Beverly2034c832018-03-19 11:18:51 -04001314 * Determine whether the device is plugged in (USB, power).
1315 * @return true if the device is plugged in wired (as opposed to wireless)
1316 */
1317 public boolean isPluggedInWired() {
1318 return plugged == BatteryManager.BATTERY_PLUGGED_AC
1319 || plugged == BatteryManager.BATTERY_PLUGGED_USB;
1320 }
1321
1322 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001323 * Whether or not the device is charged. Note that some devices never return 100% for
1324 * battery level, so this allows either battery level or status to determine if the
1325 * battery is charged.
1326 * @return true if the device is charged
1327 */
1328 public boolean isCharged() {
1329 return status == BATTERY_STATUS_FULL || level >= 100;
1330 }
1331
1332 /**
1333 * Whether battery is low and needs to be charged.
1334 * @return true if battery is low
1335 */
1336 public boolean isBatteryLow() {
1337 return level < LOW_BATTERY_THRESHOLD;
1338 }
1339
Adrian Roos7b043112015-07-10 13:00:33 -07001340 public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
Adrian Roos0c859ae2015-11-23 16:47:50 -08001341 return maxChargingWattage <= 0 ? CHARGING_UNKNOWN :
1342 maxChargingWattage < slowThreshold ? CHARGING_SLOWLY :
1343 maxChargingWattage > fastThreshold ? CHARGING_FAST :
Adrian Roos7b043112015-07-10 13:00:33 -07001344 CHARGING_REGULAR;
1345 }
Lucas Dupin3fcdd472018-01-19 19:06:45 -08001346
1347 @Override
1348 public String toString() {
1349 return "BatteryStatus{status=" + status + ",level=" + level + ",plugged=" + plugged
1350 + ",health=" + health + ",maxChargingWattage=" + maxChargingWattage + "}";
1351 }
Jim Miller16464b82011-10-20 21:10:13 -07001352 }
1353
Lucas Dupin3d053532019-01-29 12:35:22 -08001354 public static class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
1355 private final Consumer<Integer> mStrongAuthRequiredChangedCallback;
1356
1357 public StrongAuthTracker(Context context,
1358 Consumer<Integer> strongAuthRequiredChangedCallback) {
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001359 super(context);
Lucas Dupin3d053532019-01-29 12:35:22 -08001360 mStrongAuthRequiredChangedCallback = strongAuthRequiredChangedCallback;
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001361 }
Adrian Roosb5e47222015-08-14 15:53:06 -07001362
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001363 public boolean isUnlockingWithBiometricAllowed() {
Adrian Roosb5e47222015-08-14 15:53:06 -07001364 int userId = getCurrentUser();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001365 return isBiometricAllowedForUser(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -07001366 }
1367
1368 public boolean hasUserAuthenticatedSinceBoot() {
1369 int userId = getCurrentUser();
1370 return (getStrongAuthForUser(userId)
1371 & STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
1372 }
1373
1374 @Override
1375 public void onStrongAuthRequiredChanged(int userId) {
Lucas Dupin3d053532019-01-29 12:35:22 -08001376 mStrongAuthRequiredChangedCallback.accept(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -07001377 }
1378 }
1379
Jim Millerdcb3d842012-08-23 19:18:12 -07001380 public static KeyguardUpdateMonitor getInstance(Context context) {
1381 if (sInstance == null) {
1382 sInstance = new KeyguardUpdateMonitor(context);
1383 }
1384 return sInstance;
1385 }
1386
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001387 protected void handleStartedWakingUp() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001388 Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001389 updateBiometricListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001390 final int count = mCallbacks.size();
1391 for (int i = 0; i < count; i++) {
1392 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1393 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001394 cb.onStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -07001395 }
1396 }
Nick Desaulniers1d396752016-07-25 15:05:33 -07001397 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -07001398 }
1399
Jorim Jaggi95e40382015-09-16 15:53:42 -07001400 protected void handleStartedGoingToSleep(int arg1) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001401 clearBiometricRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -07001402 final int count = mCallbacks.size();
1403 for (int i = 0; i < count; i++) {
1404 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1405 if (cb != null) {
Jorim Jaggi95e40382015-09-16 15:53:42 -07001406 cb.onStartedGoingToSleep(arg1);
1407 }
1408 }
1409 mGoingToSleep = true;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001410 updateBiometricListeningState();
Jorim Jaggi95e40382015-09-16 15:53:42 -07001411 }
1412
1413 protected void handleFinishedGoingToSleep(int arg1) {
1414 mGoingToSleep = false;
1415 final int count = mCallbacks.size();
1416 for (int i = 0; i < count; i++) {
1417 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1418 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001419 cb.onFinishedGoingToSleep(arg1);
Jim Miller20daffd2013-10-07 14:59:53 -07001420 }
1421 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001422 updateBiometricListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001423 }
1424
Jorim Jaggif1518da2015-07-30 11:56:36 -07001425 private void handleScreenTurnedOn() {
1426 final int count = mCallbacks.size();
1427 for (int i = 0; i < count; i++) {
1428 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1429 if (cb != null) {
1430 cb.onScreenTurnedOn();
1431 }
1432 }
1433 }
1434
1435 private void handleScreenTurnedOff() {
Lucas Dupinca88e5f2019-05-14 16:11:08 -07001436 mLockIconPressed = false;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001437 mHardwareFingerprintUnavailableRetryCount = 0;
1438 mHardwareFaceUnavailableRetryCount = 0;
Jorim Jaggif1518da2015-07-30 11:56:36 -07001439 final int count = mCallbacks.size();
1440 for (int i = 0; i < count; i++) {
1441 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1442 if (cb != null) {
1443 cb.onScreenTurnedOff();
1444 }
1445 }
1446 }
1447
Selim Cinek99415392016-09-09 14:58:41 -07001448 private void handleDreamingStateChanged(int dreamStart) {
1449 final int count = mCallbacks.size();
Kevin Chyn36778ff2017-09-07 19:55:38 -07001450 mIsDreaming = dreamStart == 1;
Selim Cinek99415392016-09-09 14:58:41 -07001451 for (int i = 0; i < count; i++) {
1452 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1453 if (cb != null) {
Kevin Chyn36778ff2017-09-07 19:55:38 -07001454 cb.onDreamingStateChanged(mIsDreaming);
Selim Cinek99415392016-09-09 14:58:41 -07001455 }
1456 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001457 updateBiometricListeningState();
Selim Cinek99415392016-09-09 14:58:41 -07001458 }
1459
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001460 private void handleUserInfoChanged(int userId) {
1461 for (int i = 0; i < mCallbacks.size(); i++) {
1462 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1463 if (cb != null) {
1464 cb.onUserInfoChanged(userId);
1465 }
1466 }
1467 }
1468
Jorim Jaggidadafd42016-09-30 07:20:25 -07001469 private void handleUserUnlocked() {
1470 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1471 for (int i = 0; i < mCallbacks.size(); i++) {
1472 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1473 if (cb != null) {
1474 cb.onUserUnlocked();
1475 }
1476 }
1477 }
1478
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001479 @VisibleForTesting
1480 protected KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001481 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -08001482 mSubscriptionManager = SubscriptionManager.from(context);
Michael Jurkafff56142012-11-28 16:51:00 -08001483 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Lucas Dupin3d053532019-01-29 12:35:22 -08001484 mStrongAuthTracker = new StrongAuthTracker(context, this::notifyStrongAuthStateChanged);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001485
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001486 // Since device can't be un-provisioned, we only need to register a content observer
1487 // to update mDeviceProvisioned when we are...
1488 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001489 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001490 }
Jim Miller47088bb2009-11-24 00:40:16 -08001491
Jim Millerbbf1a742012-07-17 18:30:30 -07001492 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Adrian Roos7b043112015-07-10 13:00:33 -07001493 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001494
Jim Millerbbf1a742012-07-17 18:30:30 -07001495 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001496 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001497 filter.addAction(Intent.ACTION_TIME_TICK);
1498 filter.addAction(Intent.ACTION_TIME_CHANGED);
1499 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
1500 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Jason Monk052082c2015-06-11 11:35:23 -04001501 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001502 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Etan Cohen47051d82015-07-06 16:19:04 -07001503 filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Fabian Kozynskiccde55d2019-06-26 10:06:09 -04001504 filter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -08001505 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -08001506 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Alex Chauff7653d2018-02-01 17:18:08 +00001507 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jason Monk7bb59302018-05-10 19:38:18 -07001508 context.registerReceiver(mBroadcastReceiver, filter, null, mHandler);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001509
Adam Cohenc276e822012-11-08 13:01:08 -08001510 final IntentFilter bootCompleteFilter = new IntentFilter();
1511 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1512 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
Jason Monk7bb59302018-05-10 19:38:18 -07001513 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter, null, mHandler);
Adam Cohenc276e822012-11-08 13:01:08 -08001514
Adrian Roos48c796c2014-09-01 14:59:23 +02001515 final IntentFilter allUserFilter = new IntentFilter();
1516 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
1517 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
1518 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
1519 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
1520 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001521 allUserFilter.addAction(ACTION_USER_UNLOCKED);
Adrian Roos48c796c2014-09-01 14:59:23 +02001522 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Jason Monk7bb59302018-05-10 19:38:18 -07001523 null, mHandler);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001524
Wink Saville071743f2015-01-12 17:11:04 -08001525 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001526 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001527 ActivityManager.getService().registerUserSwitchObserver(
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001528 new UserSwitchObserver() {
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001529 @Override
1530 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001531 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001532 newUserId, 0, reply));
1533 }
1534 @Override
1535 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001536 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +02001537 newUserId, 0));
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001538 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001539 }, TAG);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001540 } catch (RemoteException e) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001541 e.rethrowAsRuntimeException();
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001542 }
Adrian Roos46842d92014-03-27 14:58:03 +01001543
Jorim Jaggi237b0612015-05-01 14:28:49 -07001544 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
1545 mTrustManager.registerTrustListener(this);
Michal Karpinskic52f8672016-11-18 11:32:45 +00001546 mLockPatternUtils = new LockPatternUtils(context);
1547 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Jim Millerf41fc962014-06-18 16:33:51 -07001548
Kevin Chyn36778ff2017-09-07 19:55:38 -07001549 mDreamManager = IDreamManager.Stub.asInterface(
1550 ServiceManager.getService(DreamService.DREAM_SERVICE));
1551
Jorim Jaggi3f124262016-11-22 13:45:17 +01001552 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
1553 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
1554 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001555 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FACE)) {
Kevin Chynb7b54a62018-09-28 18:48:12 -07001556 mFaceManager = (FaceManager) context.getSystemService(Context.FACE_SERVICE);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001557 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07001558
1559 if (mFpm != null || mFaceManager != null) {
1560 mBiometricManager = context.getSystemService(BiometricManager.class);
1561 mBiometricManager.registerEnabledOnKeyguardCallback(mBiometricEnabledCallback);
1562 }
1563
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001564 updateBiometricListeningState();
Jorim Jaggi3a464782015-08-28 16:59:13 -07001565 if (mFpm != null) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001566 mFpm.addLockoutResetCallback(mFingerprintLockoutResetCallback);
1567 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07001568 if (mFaceManager != null) {
1569 mFaceManager.addLockoutResetCallback(mFaceLockoutResetCallback);
Jorim Jaggi3a464782015-08-28 16:59:13 -07001570 }
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001571
Winson Chung2cf6ad82017-11-09 17:36:59 -08001572 ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001573 mUserManager = context.getSystemService(UserManager.class);
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001574 mIsPrimaryUser = mUserManager.isPrimaryUser();
Alex Chauff7653d2018-02-01 17:18:08 +00001575 mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
1576 mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
Bill Linef81cbd2018-07-05 17:48:49 +08001577 updateAirplaneModeState();
Fabian Kozynskiccde55d2019-06-26 10:06:09 -04001578
1579 TelephonyManager telephony =
1580 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
1581 if (telephony != null) {
1582 telephony.listen(mPhoneStateListener, LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE);
1583 }
Bill Linef81cbd2018-07-05 17:48:49 +08001584 }
1585
1586 private void updateAirplaneModeState() {
1587 // ACTION_AIRPLANE_MODE_CHANGED do not broadcast if device set AirplaneMode ON and boot
1588 if (!WirelessUtils.isAirplaneModeOn(mContext)
1589 || mHandler.hasMessages(MSG_AIRPLANE_MODE_CHANGED)) {
1590 return;
1591 }
1592 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Jorim Jaggiea657062015-04-28 13:45:11 -07001593 }
1594
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001595 private void updateBiometricListeningState() {
1596 updateFingerprintListeningState();
1597 updateFaceListeningState();
1598 }
1599
Jorim Jaggiea657062015-04-28 13:45:11 -07001600 private void updateFingerprintListeningState() {
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001601 // If this message exists, we should not authenticate again until this message is
1602 // consumed by the handler
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001603 if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001604 return;
1605 }
Kevin Chyn0c45b072017-04-24 16:27:11 -07001606 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
Jorim Jaggiea657062015-04-28 13:45:11 -07001607 boolean shouldListenForFingerprint = shouldListenForFingerprint();
Adrian Roos2aaf9442018-11-20 16:57:33 +01001608 boolean runningOrRestarting = mFingerprintRunningState == BIOMETRIC_STATE_RUNNING
1609 || mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING;
1610 if (runningOrRestarting && !shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001611 stopListeningForFingerprint();
Adrian Roos2aaf9442018-11-20 16:57:33 +01001612 } else if (!runningOrRestarting && shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001613 startListeningForFingerprint();
1614 }
1615 }
1616
Lucas Dupin3d053532019-01-29 12:35:22 -08001617 /**
Lucas Dupine0516d52019-02-05 17:54:06 -05001618 * Called whenever passive authentication is requested or aborted by a sensor.
1619 * @param active If the interrupt started or ended.
Lucas Dupin3d053532019-01-29 12:35:22 -08001620 */
Lucas Dupine0516d52019-02-05 17:54:06 -05001621 public void onAuthInterruptDetected(boolean active) {
1622 if (DEBUG) Log.d(TAG, "onAuthInterruptDetected(" + active + ")");
1623 if (mAuthInterruptActive == active) {
1624 return;
1625 }
1626 mAuthInterruptActive = active;
Lucas Dupin3d053532019-01-29 12:35:22 -08001627 updateFaceListeningState();
1628 }
1629
Lucas Dupin8f3faac2019-03-12 15:28:49 -07001630 /**
1631 * Requests face authentication if we're on a state where it's allowed.
1632 * This will re-trigger auth in case it fails.
1633 */
1634 public void requestFaceAuth() {
1635 if (DEBUG) Log.d(TAG, "requestFaceAuth()");
1636 updateFaceListeningState();
1637 }
1638
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001639 private void updateFaceListeningState() {
1640 // If this message exists, we should not authenticate again until this message is
1641 // consumed by the handler
1642 if (mHandler.hasMessages(MSG_BIOMETRIC_AUTHENTICATION_CONTINUE)) {
1643 return;
1644 }
1645 mHandler.removeCallbacks(mRetryFaceAuthentication);
1646 boolean shouldListenForFace = shouldListenForFace();
1647 if (mFaceRunningState == BIOMETRIC_STATE_RUNNING && !shouldListenForFace) {
1648 stopListeningForFace();
1649 } else if (mFaceRunningState != BIOMETRIC_STATE_RUNNING
1650 && shouldListenForFace) {
1651 startListeningForFace();
1652 }
1653 }
1654
Kevin Chyn129f60f2017-08-11 17:24:42 -07001655 private boolean shouldListenForFingerprintAssistant() {
1656 return mAssistantVisible && mKeyguardOccluded
1657 && !mUserFingerprintAuthenticated.get(getCurrentUser(), false)
1658 && !mUserHasTrust.get(getCurrentUser(), false);
1659 }
1660
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001661 private boolean shouldListenForFaceAssistant() {
1662 return mAssistantVisible && mKeyguardOccluded
1663 && !mUserFaceAuthenticated.get(getCurrentUser(), false)
1664 && !mUserHasTrust.get(getCurrentUser(), false);
1665 }
1666
Jorim Jaggiea657062015-04-28 13:45:11 -07001667 private boolean shouldListenForFingerprint() {
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001668 // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
1669 // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
1670 final boolean shouldListen = (mKeyguardIsVisible || !mDeviceInteractive ||
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001671 (mBouncer && !mKeyguardGoingAway) || mGoingToSleep ||
Kevin Chyn36778ff2017-09-07 19:55:38 -07001672 shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming))
Lucas Dupinc12fad32019-05-14 20:59:17 +00001673 && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser())
Kevin Chyn225eea72019-03-06 16:42:00 -08001674 && (!mKeyguardGoingAway || !mDeviceInteractive) && mIsPrimaryUser;
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001675 return shouldListen;
Jim Miller9f0753f2015-03-23 23:59:22 -07001676 }
1677
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001678 private boolean shouldListenForFace() {
Lucas Dupin3d053532019-01-29 12:35:22 -08001679 final boolean awakeKeyguard = mKeyguardIsVisible && mDeviceInteractive && !mGoingToSleep;
1680 final int user = getCurrentUser();
Robert Snoeberger5dcdf352019-06-24 11:28:28 -04001681 final int strongAuth = mStrongAuthTracker.getStrongAuthForUser(user);
1682 final boolean isLockOutOrLockDown =
1683 strongAuth == StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT
1684 || strongAuth == StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
Lucas Dupin9e484aa2019-06-24 13:38:00 -07001685
1686 // There's no reason to ask the HAL for authentication when the user can dismiss the
1687 // bouncer, unless we're bypassing and need to auto-dismiss the lock screen even when
1688 // TrustAgents or biometrics are keeping the device unlocked.
1689 boolean bypassEnabled = mKeyguardBypassController != null
1690 && mKeyguardBypassController.getBypassEnabled();
1691 boolean becauseCannotSkipBouncer = !getUserCanSkipBouncer(user) || bypassEnabled;
1692
Kevin Chynfdfd2d32019-03-01 14:52:15 -08001693 // Only listen if this KeyguardUpdateMonitor belongs to the primary user. There is an
1694 // instance of KeyguardUpdateMonitor for each user but KeyguardUpdateMonitor is user-aware.
Lucas Dupine0516d52019-02-05 17:54:06 -05001695 return (mBouncer || mAuthInterruptActive || awakeKeyguard || shouldListenForFaceAssistant())
Lucas Dupin9e484aa2019-06-24 13:38:00 -07001696 && !mSwitchingUser && !isFaceDisabled(user) && becauseCannotSkipBouncer
Lucas Dupinca88e5f2019-05-14 16:11:08 -07001697 && !mKeyguardGoingAway && mFaceSettingEnabledForUser && !mLockIconPressed
Kevin Chyn6951d3d2019-06-10 14:07:13 -07001698 && mUserManager.isUserUnlocked(user) && mIsPrimaryUser
Robert Snoeberger5dcdf352019-06-24 11:28:28 -04001699 && !mSecureCameraLaunched && !isLockOutOrLockDown;
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001700 }
1701
Lucas Dupinca88e5f2019-05-14 16:11:08 -07001702 /**
1703 * Whenever the lock icon is long pressed, disabling trust agents.
1704 * This means that we cannot auth passively (face) until the user presses power.
1705 */
1706 public void onLockIconPressed() {
1707 mLockIconPressed = true;
1708 mUserFaceAuthenticated.put(getCurrentUser(), false);
1709 updateFaceListeningState();
1710 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001711
Jim Millerce7eb6d2015-04-03 19:29:13 -07001712 private void startListeningForFingerprint() {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001713 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING) {
1714 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001715 return;
1716 }
Adrian Roos2aaf9442018-11-20 16:57:33 +01001717 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1718 // Waiting for restart via handleFingerprintError().
1719 return;
1720 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001721 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Lucas Dupin8f3faac2019-03-12 15:28:49 -07001722 int userId = getCurrentUser();
Jorim Jaggi71448a72015-08-18 19:49:04 -07001723 if (isUnlockWithFingerprintPossible(userId)) {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001724 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001725 mFingerprintCancelSignal.cancel();
1726 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001727 mFingerprintCancelSignal = new CancellationSignal();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001728 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mFingerprintAuthenticationCallback,
1729 null, userId);
1730 setFingerprintRunningState(BIOMETRIC_STATE_RUNNING);
1731 }
1732 }
1733
1734 private void startListeningForFace() {
1735 if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING) {
1736 setFaceRunningState(BIOMETRIC_STATE_CANCELLING_RESTARTING);
1737 return;
1738 }
1739 if (DEBUG) Log.v(TAG, "startListeningForFace()");
Lucas Dupin8f3faac2019-03-12 15:28:49 -07001740 int userId = getCurrentUser();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001741 if (isUnlockWithFacePossible(userId)) {
1742 if (mFaceCancelSignal != null) {
1743 mFaceCancelSignal.cancel();
1744 }
1745 mFaceCancelSignal = new CancellationSignal();
Kevin Chynb7b54a62018-09-28 18:48:12 -07001746 mFaceManager.authenticate(null, mFaceCancelSignal, 0,
Kevin Chyn8d2694a2019-04-11 18:30:40 -07001747 mFaceAuthenticationCallback, null, userId);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001748 setFaceRunningState(BIOMETRIC_STATE_RUNNING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001749 }
1750 }
1751
Lucas Dupin8d48fc42019-04-25 14:34:12 -07001752 /**
1753 * If biometrics hardware is available, not disabled, and user has enrolled templates.
1754 * This does NOT check if the device is encrypted or in lockdown.
1755 *
1756 * @param userId User that's trying to unlock.
1757 * @return {@code true} if possible.
1758 */
1759 public boolean isUnlockingWithBiometricsPossible(int userId) {
1760 return isUnlockWithFacePossible(userId) || isUnlockWithFingerprintPossible(userId);
1761 }
1762
1763 private boolean isUnlockWithFingerprintPossible(int userId) {
Selim Cinek3122fa82015-06-18 01:38:59 -07001764 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
1765 && mFpm.getEnrolledFingerprints(userId).size() > 0;
1766 }
1767
Lucas Dupin7156bc72019-05-03 19:37:39 -07001768 /**
1769 * If face hardware is available and user has enrolled. Not considering encryption or
1770 * lockdown state.
1771 */
1772 public boolean isUnlockWithFacePossible(int userId) {
Kevin Chynb7b54a62018-09-28 18:48:12 -07001773 return mFaceManager != null && mFaceManager.isHardwareDetected()
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001774 && !isFaceDisabled(userId)
Kevin Chynb7b54a62018-09-28 18:48:12 -07001775 && mFaceManager.hasEnrolledTemplates(userId);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001776 }
1777
Jorim Jaggiea657062015-04-28 13:45:11 -07001778 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001779 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001780 if (mFingerprintRunningState == BIOMETRIC_STATE_RUNNING) {
Kevin Chyn2fefd462017-04-28 12:18:19 -07001781 if (mFingerprintCancelSignal != null) {
1782 mFingerprintCancelSignal.cancel();
1783 mFingerprintCancelSignal = null;
1784 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001785 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001786 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02001787 if (mFingerprintRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1788 setFingerprintRunningState(BIOMETRIC_STATE_CANCELLING);
1789 }
1790 }
1791
1792 private void stopListeningForFace() {
1793 if (DEBUG) Log.v(TAG, "stopListeningForFace()");
1794 if (mFaceRunningState == BIOMETRIC_STATE_RUNNING) {
1795 if (mFaceCancelSignal != null) {
1796 mFaceCancelSignal.cancel();
1797 mFaceCancelSignal = null;
1798 }
1799 setFaceRunningState(BIOMETRIC_STATE_CANCELLING);
1800 }
1801 if (mFaceRunningState == BIOMETRIC_STATE_CANCELLING_RESTARTING) {
1802 setFaceRunningState(BIOMETRIC_STATE_CANCELLING);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001803 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001804 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001805
Michael Jurkafff56142012-11-28 16:51:00 -08001806 private boolean isDeviceProvisionedInSettingsDb() {
1807 return Settings.Global.getInt(mContext.getContentResolver(),
1808 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1809 }
1810
Jim Millerbbf1a742012-07-17 18:30:30 -07001811 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -08001812 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001813 @Override
1814 public void onChange(boolean selfChange) {
1815 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -08001816 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001817 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001818 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001819 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001820 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001821 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001822 };
1823
1824 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -07001825 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -08001826 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -07001827
1828 // prevent a race condition between where we check the flag and where we register the
1829 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -08001830 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001831 if (provisioned != mDeviceProvisioned) {
1832 mDeviceProvisioned = provisioned;
1833 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001834 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001835 }
1836 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001837 }
1838
Jim Millerbbf1a742012-07-17 18:30:30 -07001839 /**
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001840 * Update the state whether Keyguard currently has a lockscreen wallpaper.
1841 *
1842 * @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper.
1843 */
1844 public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001845 checkIsHandlerThread();
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001846 if (hasLockscreenWallpaper != mHasLockscreenWallpaper) {
1847 mHasLockscreenWallpaper = hasLockscreenWallpaper;
1848 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1849 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1850 if (cb != null) {
1851 cb.onHasLockscreenWallpaperChanged(hasLockscreenWallpaper);
1852 }
1853 }
1854 }
1855 }
1856
1857 /**
1858 * @return Whether Keyguard has a lockscreen wallpaper.
1859 */
1860 public boolean hasLockscreenWallpaper() {
1861 return mHasLockscreenWallpaper;
1862 }
1863
1864 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001865 * Handle {@link #MSG_DPM_STATE_CHANGED}
1866 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001867 private void handleDevicePolicyManagerStateChanged() {
Adrian Roos733b6632015-08-21 14:32:35 -07001868 updateFingerprintListeningState();
Jim Millerdcb3d842012-08-23 19:18:12 -07001869 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1870 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1871 if (cb != null) {
1872 cb.onDevicePolicyManagerStateChanged();
1873 }
Jim Millerb0304762012-03-13 20:01:25 -07001874 }
1875 }
1876
Jim Millerbbf1a742012-07-17 18:30:30 -07001877 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001878 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -07001879 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001880 private void handleUserSwitching(int userId, IRemoteCallback reply) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001881 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001882 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1883 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001884 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -07001885 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001886 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001887 try {
1888 reply.sendResult(null);
1889 } catch (RemoteException e) {
1890 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001891 }
1892
Jim Millerbbf1a742012-07-17 18:30:30 -07001893 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001894 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
1895 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001896 private void handleUserSwitchComplete(int userId) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001897 for (int i = 0; i < mCallbacks.size(); i++) {
1898 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1899 if (cb != null) {
1900 cb.onUserSwitchComplete(userId);
1901 }
1902 }
1903 }
1904
1905 /**
Jim Miller90873d52013-09-26 18:11:38 -07001906 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
1907 * keyguard crashes sometime after boot, then it will never receive this
1908 * broadcast and hence not handle the event. This method is ultimately called by
1909 * PhoneWindowManager in this case.
1910 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001911 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001912 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -07001913 }
1914
1915 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001916 * Handle {@link #MSG_BOOT_COMPLETED}
1917 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001918 private void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001919 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001920 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001921 for (int i = 0; i < mCallbacks.size(); i++) {
1922 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1923 if (cb != null) {
1924 cb.onBootCompleted();
1925 }
1926 }
1927 }
1928
1929 /**
Jim Miller5ecd8112013-01-09 18:50:26 -08001930 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001931 * destroyed.
1932 */
1933 public boolean hasBootCompleted() {
1934 return mBootCompleted;
1935 }
1936
1937 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001938 * Handle {@link #MSG_DEVICE_PROVISIONED}
1939 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001940 private void handleDeviceProvisioned() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001941 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001942 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1943 if (cb != null) {
1944 cb.onDeviceProvisioned();
1945 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001946 }
Michael Jurkafff56142012-11-28 16:51:00 -08001947 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001948 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -08001949 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
1950 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001951 }
1952 }
1953
Jim Millerbbf1a742012-07-17 18:30:30 -07001954 /**
1955 * Handle {@link #MSG_PHONE_STATE_CHANGED}
1956 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001957 private void handlePhoneStateChanged(String newState) {
Jim Millerc23024d2010-02-24 15:37:00 -08001958 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001959 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
1960 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
1961 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
1962 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
1963 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
1964 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
1965 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001966 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001967 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1968 if (cb != null) {
1969 cb.onPhoneStateChanged(mPhoneState);
1970 }
Jim Millerc23024d2010-02-24 15:37:00 -08001971 }
1972 }
1973
Jim Millerbbf1a742012-07-17 18:30:30 -07001974 /**
1975 * Handle {@link #MSG_RINGER_MODE_CHANGED}
1976 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001977 private void handleRingerModeChange(int mode) {
Jim Miller47088bb2009-11-24 00:40:16 -08001978 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001979 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -07001980 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001981 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1982 if (cb != null) {
1983 cb.onRingerModeChanged(mode);
1984 }
Jim Miller47088bb2009-11-24 00:40:16 -08001985 }
1986 }
1987
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001988 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001989 * Handle {@link #MSG_TIME_UPDATE}
1990 */
1991 private void handleTimeUpdate() {
1992 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001993 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001994 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1995 if (cb != null) {
1996 cb.onTimeChanged();
1997 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001998 }
1999 }
2000
2001 /**
Robert Snoeberger9c1074f2018-12-07 17:35:21 -05002002 * Handle (@line #MSG_TIMEZONE_UPDATE}
2003 */
2004 private void handleTimeZoneUpdate(String timeZone) {
2005 if (DEBUG) Log.d(TAG, "handleTimeZoneUpdate");
2006 for (int i = 0; i < mCallbacks.size(); i++) {
2007 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2008 if (cb != null) {
2009 cb.onTimeZoneChanged(TimeZone.getTimeZone(timeZone));
2010 // Also notify callbacks about time change to remain compatible.
2011 cb.onTimeChanged();
2012 }
2013 }
2014 }
2015
2016 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002017 * Handle {@link #MSG_BATTERY_UPDATE}
2018 */
Jim Millerbbf1a742012-07-17 18:30:30 -07002019 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002020 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07002021 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
2022 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07002023 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002024 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002025 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2026 if (cb != null) {
2027 cb.onRefreshBatteryInfo(status);
2028 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002029 }
2030 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002031 }
2032
2033 /**
Bill Linef81cbd2018-07-05 17:48:49 +08002034 * Handle Telephony status during Boot for CarrierText display policy
2035 */
2036 @VisibleForTesting
2037 void updateTelephonyCapable(boolean capable){
2038 if (capable == mTelephonyCapable) {
2039 return;
2040 }
2041 mTelephonyCapable = capable;
2042 for (WeakReference<KeyguardUpdateMonitorCallback> ref : mCallbacks) {
2043 KeyguardUpdateMonitorCallback cb = ref.get();
2044 if (cb != null) {
2045 cb.onTelephonyCapable(mTelephonyCapable);
2046 }
2047 }
2048 }
2049
2050 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002051 * Handle {@link #MSG_SIM_STATE_CHANGE}
2052 */
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08002053 @VisibleForTesting
Adrian Roos30a2ae62018-04-25 19:09:50 +02002054 void handleSimStateChange(int subId, int slotId, State state) {
2055 checkIsHandlerThread();
Jim Miller52a61332014-11-12 19:29:51 -08002056 if (DEBUG_SIM_STATES) {
2057 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
2058 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002059 }
2060
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002061 boolean becameAbsent = false;
Wink Savillea54bf652014-12-11 13:37:50 -08002062 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08002063 Log.w(TAG, "invalid subId in handleSimStateChange()");
andychou695a7602019-05-16 23:14:00 +08002064 /* Only handle No SIM(ABSENT) and Card Error(CARD_IO_ERROR) due to
2065 * handleServiceStateChange() handle other case */
Bill Linef81cbd2018-07-05 17:48:49 +08002066 if (state == State.ABSENT) {
2067 updateTelephonyCapable(true);
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002068 // Even though the subscription is not valid anymore, we need to notify that the
2069 // SIM card was removed so we can update the UI.
2070 becameAbsent = true;
Brad Ebingere6c6f722018-12-20 21:11:44 -08002071 for (SimData data : mSimDatas.values()) {
2072 // Set the SIM state of all SimData associated with that slot to ABSENT se we
2073 // do not move back into PIN/PUK locked and not detect the change below.
2074 if (data.slotId == slotId) {
2075 data.simState = State.ABSENT;
2076 }
2077 }
andychou695a7602019-05-16 23:14:00 +08002078 } else if (state == State.CARD_IO_ERROR) {
2079 updateTelephonyCapable(true);
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002080 } else {
2081 return;
Bill Linef81cbd2018-07-05 17:48:49 +08002082 }
Jim Miller52a61332014-11-12 19:29:51 -08002083 }
2084
2085 SimData data = mSimDatas.get(subId);
2086 final boolean changed;
2087 if (data == null) {
2088 data = new SimData(state, slotId, subId);
2089 mSimDatas.put(subId, data);
2090 changed = true; // no data yet; force update
2091 } else {
2092 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
2093 data.simState = state;
2094 data.subId = subId;
2095 data.slotId = slotId;
2096 }
Lucas Dupin2e0d4952018-12-05 20:03:53 -08002097 if ((changed || becameAbsent) && state != State.UNKNOWN) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002098 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07002099 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2100 if (cb != null) {
Jim Miller52a61332014-11-12 19:29:51 -08002101 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07002102 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002103 }
2104 }
2105 }
2106
Jim Millerbbf1a742012-07-17 18:30:30 -07002107 /**
Etan Cohen47051d82015-07-06 16:19:04 -07002108 * Handle {@link #MSG_SERVICE_STATE_CHANGE}
2109 */
Bill Linef81cbd2018-07-05 17:48:49 +08002110 @VisibleForTesting
2111 void handleServiceStateChange(int subId, ServiceState serviceState) {
Etan Cohen47051d82015-07-06 16:19:04 -07002112 if (DEBUG) {
2113 Log.d(TAG,
2114 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
2115 }
2116
2117 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
2118 Log.w(TAG, "invalid subId in handleServiceStateChange()");
2119 return;
Bill Linef81cbd2018-07-05 17:48:49 +08002120 } else {
2121 updateTelephonyCapable(true);
Etan Cohen47051d82015-07-06 16:19:04 -07002122 }
2123
2124 mServiceStates.put(subId, serviceState);
2125
2126 for (int j = 0; j < mCallbacks.size(); j++) {
2127 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
2128 if (cb != null) {
2129 cb.onRefreshCarrierInfo();
2130 }
2131 }
2132 }
2133
Lucas Dupinf8463ee2018-06-11 16:18:15 -07002134 public boolean isKeyguardVisible() {
2135 return mKeyguardIsVisible;
2136 }
2137
Etan Cohen47051d82015-07-06 16:19:04 -07002138 /**
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002139 * Notifies that the visibility state of Keyguard has changed.
2140 *
2141 * <p>Needs to be called from the main thread.
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002142 */
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002143 public void onKeyguardVisibilityChanged(boolean showing) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002144 checkIsHandlerThread();
Kevin Chynb4514d22019-04-15 13:47:25 -07002145 Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002146 mKeyguardIsVisible = showing;
Kevin Chyn6951d3d2019-06-10 14:07:13 -07002147
2148 if (showing) {
2149 mSecureCameraLaunched = false;
2150 }
2151
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002152 for (int i = 0; i < mCallbacks.size(); i++) {
2153 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2154 if (cb != null) {
Jorim Jaggi6a15d522015-09-22 15:55:33 -07002155 cb.onKeyguardVisibilityChangedRaw(showing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002156 }
2157 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002158 updateBiometricListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04002159 }
2160
Brian Colonna7fce3802013-09-17 15:51:32 -04002161 /**
Selim Cinek1fcafc42015-07-20 14:39:25 -07002162 * Handle {@link #MSG_KEYGUARD_RESET}
2163 */
2164 private void handleKeyguardReset() {
2165 if (DEBUG) Log.d(TAG, "handleKeyguardReset");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002166 updateBiometricListeningState();
Jorim Jaggi031f7952016-09-01 16:39:26 -07002167 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
2168 }
2169
2170 private boolean resolveNeedsSlowUnlockTransition() {
2171 if (mUserManager.isUserUnlocked(getCurrentUser())) {
2172 return false;
2173 }
2174 Intent homeIntent = new Intent(Intent.ACTION_MAIN)
2175 .addCategory(Intent.CATEGORY_HOME);
2176 ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(homeIntent,
2177 0 /* flags */);
2178 return FALLBACK_HOME_COMPONENT.equals(resolveInfo.getComponentInfo().getComponentName());
Selim Cinek1fcafc42015-07-20 14:39:25 -07002179 }
2180
2181 /**
Adrian Roosb6011622014-05-14 15:52:53 +02002182 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
2183 * @see #sendKeyguardBouncerChanged(boolean)
2184 */
2185 private void handleKeyguardBouncerChanged(int bouncer) {
2186 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
2187 boolean isBouncer = (bouncer == 1);
2188 mBouncer = isBouncer;
2189 for (int i = 0; i < mCallbacks.size(); i++) {
2190 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2191 if (cb != null) {
2192 cb.onKeyguardBouncerChanged(isBouncer);
2193 }
2194 }
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002195 updateBiometricListeningState();
Adrian Roosb6011622014-05-14 15:52:53 +02002196 }
2197
2198 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04002199 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
2200 */
2201 private void handleReportEmergencyCallAction() {
2202 for (int i = 0; i < mCallbacks.size(); i++) {
2203 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2204 if (cb != null) {
2205 cb.onEmergencyCallAction();
2206 }
2207 }
2208 }
2209
Lucas Dupin4272f442018-01-13 22:00:35 -08002210 private boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07002211 final boolean nowPluggedIn = current.isPluggedIn();
2212 final boolean wasPluggedIn = old.isPluggedIn();
Lucas Dupin4272f442018-01-13 22:00:35 -08002213 final boolean stateChangedWhilePluggedIn = wasPluggedIn && nowPluggedIn
Jim Miller16464b82011-10-20 21:10:13 -07002214 && (old.status != current.status);
2215
2216 // change in plug state is always interesting
2217 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002218 return true;
2219 }
2220
Lucas Dupin3fcdd472018-01-19 19:06:45 -08002221 // change in battery level
2222 if (old.level != current.level) {
Jim Miller16464b82011-10-20 21:10:13 -07002223 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002224 }
Adrian Roos76dc5a52015-07-21 16:20:36 -07002225
2226 // change in charging current while plugged in
Adrian Roos0c859ae2015-11-23 16:47:50 -08002227 if (nowPluggedIn && current.maxChargingWattage != old.maxChargingWattage) {
Adrian Roos76dc5a52015-07-21 16:20:36 -07002228 return true;
2229 }
2230
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002231 return false;
2232 }
2233
2234 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07002235 * Remove the given observer's callback.
2236 *
Jim Miller6212cc02012-09-05 17:35:31 -07002237 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002238 */
Jim Miller6212cc02012-09-05 17:35:31 -07002239 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002240 checkIsHandlerThread();
Jim Miller6212cc02012-09-05 17:35:31 -07002241 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
2242 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
2243 if (mCallbacks.get(i).get() == callback) {
2244 mCallbacks.remove(i);
2245 }
2246 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002247 }
2248
2249 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002250 * Register to receive notifications about general keyguard information
2251 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07002252 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002253 */
Jim Millerbbf1a742012-07-17 18:30:30 -07002254 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002255 checkIsHandlerThread();
Jim Miller6212cc02012-09-05 17:35:31 -07002256 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
2257 // Prevent adding duplicate callbacks
2258 for (int i = 0; i < mCallbacks.size(); i++) {
2259 if (mCallbacks.get(i).get() == callback) {
2260 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
2261 new Exception("Called by"));
2262 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07002263 }
2264 }
Jim Miller6212cc02012-09-05 17:35:31 -07002265 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
2266 removeCallback(null); // remove unused references
2267 sendUpdates(callback);
2268 }
2269
Lucas Dupin9e484aa2019-06-24 13:38:00 -07002270 public void setKeyguardBypassController(KeyguardBypassController keyguardBypassController) {
2271 mKeyguardBypassController = keyguardBypassController;
2272 }
2273
Lucas Dupinc12fad32019-05-14 20:59:17 +00002274 public boolean isSwitchingUser() {
2275 return mSwitchingUser;
2276 }
2277
Adrian Roos30a2ae62018-04-25 19:09:50 +02002278 @AnyThread
Evan Rosky18396452016-07-27 15:19:37 -07002279 public void setSwitchingUser(boolean switching) {
Lucas Dupinc12fad32019-05-14 20:59:17 +00002280 mSwitchingUser = switching;
Selim Cinekbbe19242017-12-08 15:42:08 -08002281 // Since this comes in on a binder thread, we need to post if first
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002282 mHandler.post(mUpdateBiometricListeningState);
Evan Rosky18396452016-07-27 15:19:37 -07002283 }
2284
Jim Miller6212cc02012-09-05 17:35:31 -07002285 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
2286 // Notify listener of the current state
2287 callback.onRefreshBatteryInfo(mBatteryStatus);
2288 callback.onTimeChanged();
2289 callback.onRingerModeChanged(mRingMode);
2290 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05002291 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07002292 callback.onClockVisibilityChanged();
Lucas Dupin16cfe452018-02-08 13:14:50 -08002293 callback.onKeyguardVisibilityChangedRaw(mKeyguardIsVisible);
Bill Linef81cbd2018-07-05 17:48:49 +08002294 callback.onTelephonyCapable(mTelephonyCapable);
Jim Miller52a61332014-11-12 19:29:51 -08002295 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
2296 final SimData state = data.getValue();
2297 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
2298 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002299 }
2300
Selim Cinek1fcafc42015-07-20 14:39:25 -07002301 public void sendKeyguardReset() {
2302 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
2303 }
2304
Adrian Roosb6011622014-05-14 15:52:53 +02002305 /**
2306 * @see #handleKeyguardBouncerChanged(int)
2307 */
2308 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
2309 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
2310 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
2311 message.arg1 = showingBouncer ? 1 : 0;
2312 message.sendToTarget();
2313 }
2314
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002315 /**
Jim Miller90d5d462011-11-17 16:57:01 -08002316 * 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 -08002317 * have the information earlier than waiting for the intent
2318 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08002319 *
2320 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
2321 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002322 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02002323 @MainThread
Jim Miller52a61332014-11-12 19:29:51 -08002324 public void reportSimUnlocked(int subId) {
2325 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
Sanket Padawe7e460252017-03-10 16:18:20 -08002326 int slotId = SubscriptionManager.getSlotIndex(subId);
Jim Miller52a61332014-11-12 19:29:51 -08002327 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002328 }
2329
Brian Colonna7fce3802013-09-17 15:51:32 -04002330 /**
2331 * Report that the emergency call button has been pressed and the emergency dialer is
2332 * about to be displayed.
2333 *
2334 * @param bypassHandler runs immediately.
2335 *
2336 * NOTE: Must be called from UI thread if bypassHandler == true.
2337 */
2338 public void reportEmergencyCallAction(boolean bypassHandler) {
2339 if (!bypassHandler) {
2340 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
2341 } else {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002342 checkIsHandlerThread();
Brian Colonna7fce3802013-09-17 15:51:32 -04002343 handleReportEmergencyCallAction();
2344 }
2345 }
2346
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002347 /**
2348 * @return Whether the device is provisioned (whether they have gone through
2349 * the setup wizard)
2350 */
2351 public boolean isDeviceProvisioned() {
2352 return mDeviceProvisioned;
2353 }
2354
Kensuke Matsui21d1bf12017-03-14 13:27:20 +09002355 public ServiceState getServiceState(int subId) {
2356 return mServiceStates.get(subId);
2357 }
2358
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002359 public void clearBiometricRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07002360 mUserFingerprintAuthenticated.clear();
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002361 mUserFaceAuthenticated.clear();
2362 mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FINGERPRINT);
2363 mTrustManager.clearAllBiometricRecognized(BiometricSourceType.FACE);
Aran Ink4c0d5602019-06-21 14:27:32 -04002364
2365 for (int i = 0; i < mCallbacks.size(); i++) {
2366 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2367 if (cb != null) {
2368 cb.onBiometricsCleared();
2369 }
2370 }
Jim Millerf41fc962014-06-18 16:33:51 -07002371 }
2372
Jim Miller52a61332014-11-12 19:29:51 -08002373 public boolean isSimPinVoiceSecure() {
2374 // TODO: only count SIMs that handle voice
2375 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07002376 }
2377
Lucas Dupin7156bc72019-05-03 19:37:39 -07002378 /**
2379 * If any SIM cards are currently secure.
2380 * @see #isSimPinSecure(State)
2381 */
Jim Millerdcb3d842012-08-23 19:18:12 -07002382 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08002383 // True if any SIM is pin secure
2384 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
2385 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
2386 }
2387 return false;
2388 }
2389
Jason Monk9ff69bd2014-12-02 16:43:17 -05002390 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08002391 if (mSimDatas.containsKey(subId)) {
2392 return mSimDatas.get(subId).simState;
2393 } else {
2394 return State.UNKNOWN;
2395 }
2396 }
2397
Winson Chung67f5c8b2018-09-24 12:09:19 -07002398 private final TaskStackChangeListener
2399 mTaskStackListener = new TaskStackChangeListener() {
Kevin Chyn2fefd462017-04-28 12:18:19 -07002400 @Override
2401 public void onTaskStackChangedBackground() {
2402 try {
Wale Ogunwale04d9cb52018-04-30 13:55:07 -07002403 ActivityManager.StackInfo info = ActivityTaskManager.getService().getStackInfo(
Wale Ogunwale68278562017-09-23 17:13:55 -07002404 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
Kevin Chyn2fefd462017-04-28 12:18:19 -07002405 if (info == null) {
2406 return;
2407 }
2408 mHandler.sendMessage(mHandler.obtainMessage(MSG_ASSISTANT_STACK_CHANGED,
2409 info.visible));
2410 } catch (RemoteException e) {
2411 Log.e(TAG, "unable to check task stack", e);
2412 }
2413 }
2414 };
2415
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002416 /**
Richard Choue0381b82018-04-24 03:48:59 +00002417 * @return true if and only if the state has changed for the specified {@code slotId}
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002418 */
Richard Choue0381b82018-04-24 03:48:59 +00002419 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08002420
2421 // This is awful. It exists because there are two APIs for getting the SIM status
2422 // that don't return the complete set of values and have different types. In Keyguard we
2423 // need IccCardConstants, but TelephonyManager would only give us
2424 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08002425 final TelephonyManager tele = TelephonyManager.from(mContext);
Richard Choue0381b82018-04-24 03:48:59 +00002426 int simState = tele.getSimState(slotId);
2427 State state;
2428 try {
2429 state = State.intToState(simState);
2430 } catch(IllegalArgumentException ex) {
2431 Log.w(TAG, "Unknown sim state: " + simState);
2432 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05002433 }
Richard Choue0381b82018-04-24 03:48:59 +00002434 SimData data = mSimDatas.get(subId);
2435 final boolean changed;
2436 if (data == null) {
2437 data = new SimData(state, slotId, subId);
2438 mSimDatas.put(subId, data);
2439 changed = true; // no data yet; force update
2440 } else {
2441 changed = data.simState != state;
2442 data.simState = state;
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01002443 }
Richard Choue0381b82018-04-24 03:48:59 +00002444 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07002445 }
2446
Lucas Dupin7156bc72019-05-03 19:37:39 -07002447 /**
2448 * If the {@code state} is currently requiring a SIM PIN, PUK, or is disabled.
2449 */
Jim Millerdcb3d842012-08-23 19:18:12 -07002450 public static boolean isSimPinSecure(IccCardConstants.State state) {
Lucas Dupin7156bc72019-05-03 19:37:39 -07002451 return (state == IccCardConstants.State.PIN_REQUIRED
2452 || state == IccCardConstants.State.PUK_REQUIRED
2453 || state == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07002454 }
Jim Miller8f09fd22013-03-14 19:04:28 -07002455
2456 public DisplayClientState getCachedDisplayClientState() {
2457 return mDisplayClientState;
2458 }
Jim Miller20daffd2013-10-07 14:59:53 -07002459
2460 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
2461 // (KeyguardViewMediator, KeyguardHostView)
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002462 public void dispatchStartedWakingUp() {
2463 synchronized (this) {
2464 mDeviceInteractive = true;
2465 }
2466 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
2467 }
2468
Jorim Jaggi95e40382015-09-16 15:53:42 -07002469 public void dispatchStartedGoingToSleep(int why) {
2470 mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
2471 }
2472
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002473 public void dispatchFinishedGoingToSleep(int why) {
2474 synchronized(this) {
2475 mDeviceInteractive = false;
2476 }
2477 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
2478 }
2479
Jim Miller20daffd2013-10-07 14:59:53 -07002480 public void dispatchScreenTurnedOn() {
2481 synchronized (this) {
2482 mScreenOn = true;
2483 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07002484 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
Jim Miller20daffd2013-10-07 14:59:53 -07002485 }
2486
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002487 public void dispatchScreenTurnedOff() {
Jim Miller20daffd2013-10-07 14:59:53 -07002488 synchronized(this) {
2489 mScreenOn = false;
2490 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07002491 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
Jim Miller20daffd2013-10-07 14:59:53 -07002492 }
2493
Selim Cinek99415392016-09-09 14:58:41 -07002494 public void dispatchDreamingStarted() {
2495 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 1, 0));
2496 }
2497
2498 public void dispatchDreamingStopped() {
2499 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 0, 0));
2500 }
2501
Jorim Jaggi0d210f62015-07-10 14:24:44 -07002502 public boolean isDeviceInteractive() {
2503 return mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -07002504 }
Jim Miller52a61332014-11-12 19:29:51 -08002505
Jorim Jaggi95e40382015-09-16 15:53:42 -07002506 public boolean isGoingToSleep() {
2507 return mGoingToSleep;
2508 }
2509
Jim Miller52a61332014-11-12 19:29:51 -08002510 /**
2511 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
2512 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08002513 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08002514 */
2515 public int getNextSubIdForState(State state) {
2516 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08002517 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08002518 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
2519 for (int i = 0; i < list.size(); i++) {
2520 final SubscriptionInfo info = list.get(i);
2521 final int id = info.getSubscriptionId();
Sanket Padawe7e460252017-03-10 16:18:20 -08002522 int slotId = SubscriptionManager.getSlotIndex(id);
Jim Miller52a61332014-11-12 19:29:51 -08002523 if (state == getSimState(id) && bestSlotId > slotId ) {
2524 resultId = id;
2525 bestSlotId = slotId;
2526 }
2527 }
2528 return resultId;
2529 }
2530
2531 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
2532 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
2533 for (int i = 0; i < list.size(); i++) {
2534 SubscriptionInfo info = list.get(i);
2535 if (subId == info.getSubscriptionId()) return info;
2536 }
2537 return null; // not found
2538 }
Jason Monkab525272015-07-13 17:02:49 -04002539
Alex Chauff7653d2018-02-01 17:18:08 +00002540 /**
2541 * @return a cached version of DevicePolicyManager.isLogoutEnabled()
2542 */
2543 public boolean isLogoutEnabled() {
2544 return mLogoutEnabled;
2545 }
2546
2547 private void updateLogoutEnabled() {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002548 checkIsHandlerThread();
Alex Chauff7653d2018-02-01 17:18:08 +00002549 boolean logoutEnabled = mDevicePolicyManager.isLogoutEnabled();
2550 if (mLogoutEnabled != logoutEnabled) {
2551 mLogoutEnabled = logoutEnabled;
2552 for (int i = 0; i < mCallbacks.size(); i++) {
2553 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2554 if (cb != null) {
2555 cb.onLogoutEnabledChanged();
2556 }
2557 }
2558 }
2559 }
2560
Adrian Roos30a2ae62018-04-25 19:09:50 +02002561 private void checkIsHandlerThread() {
2562 if (sDisableHandlerCheckForTesting) {
2563 return;
2564 }
2565 if (!mHandler.getLooper().isCurrentThread()) {
2566 Log.wtf(TAG, "must call on mHandler's thread "
2567 + mHandler.getLooper().getThread() + ", not " + Thread.currentThread());
2568 }
2569 }
2570
2571 /**
2572 * Turn off the handler check for testing.
2573 *
2574 * This is necessary because currently tests are not too careful about which thread they call
2575 * into this class on.
2576 *
2577 * Note that this must be called before scheduling any work involving KeyguardUpdateMonitor
2578 * instances.
2579 *
2580 * TODO: fix the tests and remove this.
2581 */
2582 @VisibleForTesting
2583 public static void disableHandlerCheckForTesting(Instrumentation instrumentation) {
2584 Preconditions.checkNotNull(instrumentation, "Must only call this method in tests!");
2585 // Don't need synchronization here *if* the callers follow the contract and call this only
2586 // before scheduling work for KeyguardUpdateMonitor on other threads, because the scheduling
2587 // of that work forces a happens-before relationship.
2588 sDisableHandlerCheckForTesting = true;
2589 }
2590
Jason Monkab525272015-07-13 17:02:49 -04002591 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2592 pw.println("KeyguardUpdateMonitor state:");
2593 pw.println(" SIM States:");
2594 for (SimData data : mSimDatas.values()) {
2595 pw.println(" " + data.toString());
2596 }
2597 pw.println(" Subs:");
2598 if (mSubscriptionInfo != null) {
2599 for (int i = 0; i < mSubscriptionInfo.size(); i++) {
2600 pw.println(" " + mSubscriptionInfo.get(i));
2601 }
2602 }
2603 pw.println(" Service states:");
2604 for (int subId : mServiceStates.keySet()) {
2605 pw.println(" " + subId + "=" + mServiceStates.get(subId));
2606 }
Jim Millerd72d5ac2015-09-29 18:55:32 -07002607 if (mFpm != null && mFpm.isHardwareDetected()) {
2608 final int userId = ActivityManager.getCurrentUser();
2609 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
2610 pw.println(" Fingerprint state (user=" + userId + ")");
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002611 pw.println(" allowed=" + isUnlockingWithBiometricAllowed());
Jim Millerd72d5ac2015-09-29 18:55:32 -07002612 pw.println(" auth'd=" + mUserFingerprintAuthenticated.get(userId));
2613 pw.println(" authSinceBoot="
2614 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
2615 pw.println(" disabled(DPM)=" + isFingerprintDisabled(userId));
2616 pw.println(" possible=" + isUnlockWithFingerprintPossible(userId));
Adrian Roos2aaf9442018-11-20 16:57:33 +01002617 pw.println(" listening: actual=" + mFingerprintRunningState
2618 + " expected=" + (shouldListenForFingerprint() ? 1 : 0));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002619 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002620 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
2621 }
Kevin Chynb7b54a62018-09-28 18:48:12 -07002622 if (mFaceManager != null && mFaceManager.isHardwareDetected()) {
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002623 final int userId = ActivityManager.getCurrentUser();
2624 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
2625 pw.println(" Face authentication state (user=" + userId + ")");
2626 pw.println(" allowed=" + isUnlockingWithBiometricAllowed());
2627 pw.println(" auth'd=" + mUserFaceAuthenticated.get(userId));
2628 pw.println(" authSinceBoot="
2629 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
2630 pw.println(" disabled(DPM)=" + isFaceDisabled(userId));
2631 pw.println(" possible=" + isUnlockWithFacePossible(userId));
2632 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
2633 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
Kevin Chynb7b54a62018-09-28 18:48:12 -07002634 pw.println(" enabledByUser=" + mFaceSettingEnabledForUser);
Gilad Brettercb51b8b2018-03-22 17:04:51 +02002635 }
Jason Monkab525272015-07-13 17:02:49 -04002636 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002637}