blob: ef3aa42727e9583c8d1053064894d9bb870c97a4 [file] [log] [blame]
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jim Miller5ecd8112013-01-09 18:50:26 -080017package com.android.keyguard;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080018
Wale Ogunwale68278562017-09-23 17:13:55 -070019import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT;
20import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
Jorim Jaggidadafd42016-09-30 07:20:25 -070021import static android.content.Intent.ACTION_USER_UNLOCKED;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070022import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
23import static android.os.BatteryManager.BATTERY_STATUS_FULL;
24import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
25import static android.os.BatteryManager.EXTRA_HEALTH;
26import static android.os.BatteryManager.EXTRA_LEVEL;
27import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
28import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
29import static android.os.BatteryManager.EXTRA_PLUGGED;
30import static android.os.BatteryManager.EXTRA_STATUS;
31
Adrian Roos30a2ae62018-04-25 19:09:50 +020032import android.annotation.AnyThread;
33import android.annotation.MainThread;
Jorim Jaggiccdfa932015-04-13 16:29:48 -070034import android.app.ActivityManager;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020035import android.app.AlarmManager;
Adrian Roos30a2ae62018-04-25 19:09:50 +020036import android.app.Instrumentation;
Jim Miller8f09fd22013-03-14 19:04:28 -070037import android.app.PendingIntent;
Sudheer Shanka2c4522c2016-08-27 20:53:28 -070038import android.app.UserSwitchObserver;
Jim Millerb0304762012-03-13 20:01:25 -070039import android.app.admin.DevicePolicyManager;
Adrian Roos46842d92014-03-27 14:58:03 +010040import android.app.trust.TrustManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080041import android.content.BroadcastReceiver;
Jorim Jaggi031f7952016-09-01 16:39:26 -070042import android.content.ComponentName;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080043import android.content.Context;
44import android.content.Intent;
45import android.content.IntentFilter;
Adrian Roosca8a2162017-08-17 19:00:58 +020046import android.content.pm.IPackageManager;
Jorim Jaggi031f7952016-09-01 16:39:26 -070047import android.content.pm.PackageManager;
48import android.content.pm.ResolveInfo;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080049import android.database.ContentObserver;
Jorim Jaggi86bed402015-08-20 18:20:02 -070050import android.hardware.fingerprint.FingerprintManager;
51import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
52import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
Jim Miller47088bb2009-11-24 00:40:16 -080053import android.media.AudioManager;
Jim Miller79a444a2011-02-15 15:02:11 -080054import android.os.BatteryManager;
Jim Miller9f0753f2015-03-23 23:59:22 -070055import android.os.CancellationSignal;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080056import android.os.Handler;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070057import android.os.IRemoteCallback;
Jason Monk7bb59302018-05-10 19:38:18 -070058import android.os.Looper;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080059import android.os.Message;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070060import android.os.RemoteException;
Adrian Roosca8a2162017-08-17 19:00:58 +020061import android.os.ServiceManager;
Nick Desaulniers1d396752016-07-25 15:05:33 -070062import android.os.Trace;
Amith Yamasanie8e93a12013-05-09 18:12:30 -070063import android.os.UserHandle;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070064import android.os.UserManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080065import android.provider.Settings;
Kevin Chyn36778ff2017-09-07 19:55:38 -070066import android.service.dreams.DreamService;
67import android.service.dreams.IDreamManager;
Etan Cohen47051d82015-07-06 16:19:04 -070068import android.telephony.ServiceState;
Jim Miller52a61332014-11-12 19:29:51 -080069import android.telephony.SubscriptionInfo;
Jim Miller52a61332014-11-12 19:29:51 -080070import android.telephony.SubscriptionManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -080071import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Jim Millerc23024d2010-02-24 15:37:00 -080072import android.telephony.TelephonyManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080073import android.util.Log;
Richard Choue0381b82018-04-24 03:48:59 +000074import android.util.Slog;
Adrian Roos46842d92014-03-27 14:58:03 +010075import android.util.SparseBooleanArray;
Jorim Jaggi9f743032015-05-04 15:22:40 -070076import android.util.SparseIntArray;
Adrian Roos46842d92014-03-27 14:58:03 +010077
Lucas Dupin7517b5d2017-08-22 12:51:25 -070078import com.android.internal.annotations.VisibleForTesting;
Jorim Jaggi86bed402015-08-20 18:20:02 -070079import com.android.internal.telephony.IccCardConstants;
80import com.android.internal.telephony.IccCardConstants.State;
81import com.android.internal.telephony.PhoneConstants;
82import com.android.internal.telephony.TelephonyIntents;
Adrian Roos30a2ae62018-04-25 19:09:50 +020083import com.android.internal.util.Preconditions;
Adrian Roosb5e47222015-08-14 15:53:06 -070084import com.android.internal.widget.LockPatternUtils;
Winson Chungaa357452017-10-31 11:35:30 -070085import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
Winson Chung2cf6ad82017-11-09 17:36:59 -080086import com.android.systemui.shared.system.ActivityManagerWrapper;
Jorim Jaggi86bed402015-08-20 18:20:02 -070087
Kevin Chyn36778ff2017-09-07 19:55:38 -070088import com.google.android.collect.Lists;
89
Jason Monkab525272015-07-13 17:02:49 -040090import java.io.FileDescriptor;
91import java.io.PrintWriter;
Jim Millerdcb3d842012-08-23 19:18:12 -070092import java.lang.ref.WeakReference;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080093import java.util.ArrayList;
Jim Miller52a61332014-11-12 19:29:51 -080094import java.util.HashMap;
95import java.util.List;
96import java.util.Map.Entry;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080097
98/**
99 * Watches for updates that may be interesting to the keyguard, and provides
100 * the up to date information as well as a registration for callbacks that care
101 * to be updated.
102 *
103 * Note: under time crunch, this has been extended to include some stuff that
104 * doesn't really belong here. see {@link #handleBatteryUpdate} where it shutdowns
Jim Miller258341c2012-08-30 16:50:10 -0700105 * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()}
106 * and {@link #clearFailedUnlockAttempts()}. Maybe we should rename this 'KeyguardContext'...
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800107 */
Adrian Roos46842d92014-03-27 14:58:03 +0100108public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800109
Jim Millerbbf1a742012-07-17 18:30:30 -0700110 private static final String TAG = "KeyguardUpdateMonitor";
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100111 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller52a61332014-11-12 19:29:51 -0800112 private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
Jim Millerbbf1a742012-07-17 18:30:30 -0700113 private static final int LOW_BATTERY_THRESHOLD = 20;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800114
Jorim Jaggie7b12522014-08-06 16:41:21 +0200115 private static final String ACTION_FACE_UNLOCK_STARTED
116 = "com.android.facelock.FACE_UNLOCK_STARTED";
117 private static final String ACTION_FACE_UNLOCK_STOPPED
118 = "com.android.facelock.FACE_UNLOCK_STOPPED";
119
Jim Millerbbf1a742012-07-17 18:30:30 -0700120 // Callback messages
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800121 private static final int MSG_TIME_UPDATE = 301;
122 private static final int MSG_BATTERY_UPDATE = 302;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800123 private static final int MSG_SIM_STATE_CHANGE = 304;
Jim Miller47088bb2009-11-24 00:40:16 -0800124 private static final int MSG_RINGER_MODE_CHANGED = 305;
Jim Millerc23024d2010-02-24 15:37:00 -0800125 private static final int MSG_PHONE_STATE_CHANGED = 306;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700126 private static final int MSG_DEVICE_PROVISIONED = 308;
Jim Miller57375342012-09-09 15:20:31 -0700127 private static final int MSG_DPM_STATE_CHANGED = 309;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500128 private static final int MSG_USER_SWITCHING = 310;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700129 private static final int MSG_KEYGUARD_RESET = 312;
Jim Millerf41fc962014-06-18 16:33:51 -0700130 private static final int MSG_BOOT_COMPLETED = 313;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500131 private static final int MSG_USER_SWITCH_COMPLETE = 314;
Jim Millerf41fc962014-06-18 16:33:51 -0700132 private static final int MSG_USER_INFO_CHANGED = 317;
133 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700134 private static final int MSG_STARTED_WAKING_UP = 319;
135 private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700136 private static final int MSG_STARTED_GOING_TO_SLEEP = 321;
Adrian Roosb6011622014-05-14 15:52:53 +0200137 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700138 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
139 private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
Jason Monk052082c2015-06-11 11:35:23 -0400140 private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
Etan Cohen47051d82015-07-06 16:19:04 -0700141 private static final int MSG_SERVICE_STATE_CHANGE = 330;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700142 private static final int MSG_SCREEN_TURNED_ON = 331;
143 private static final int MSG_SCREEN_TURNED_OFF = 332;
Selim Cinek99415392016-09-09 14:58:41 -0700144 private static final int MSG_DREAMING_STATE_CHANGED = 333;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700145 private static final int MSG_USER_UNLOCKED = 334;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700146 private static final int MSG_ASSISTANT_STACK_CHANGED = 335;
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700147 private static final int MSG_FINGERPRINT_AUTHENTICATION_CONTINUE = 336;
Alex Chauff7653d2018-02-01 17:18:08 +0000148 private static final int MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED = 337;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800149
Jorim Jaggi86bed402015-08-20 18:20:02 -0700150 /** Fingerprint state: Not listening to fingerprint. */
151 private static final int FINGERPRINT_STATE_STOPPED = 0;
152
153 /** Fingerprint state: Listening. */
154 private static final int FINGERPRINT_STATE_RUNNING = 1;
155
156 /**
157 * Fingerprint state: Cancelling and waiting for the confirmation from FingerprintService to
158 * send us the confirmation that cancellation has happened.
159 */
160 private static final int FINGERPRINT_STATE_CANCELLING = 2;
161
162 /**
163 * Fingerprint state: During cancelling we got another request to start listening, so when we
164 * receive the cancellation done signal, we should start listening again.
165 */
166 private static final int FINGERPRINT_STATE_CANCELLING_RESTARTING = 3;
167
Adrian Roos0c859ae2015-11-23 16:47:50 -0800168 private static final int DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT = 5000000;
169
Jorim Jaggi031f7952016-09-01 16:39:26 -0700170 private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName(
171 "com.android.settings", "com.android.settings.FallbackHome");
172
Adrian Roosca8a2162017-08-17 19:00:58 +0200173
174 /**
175 * If true, the system is in the half-boot-to-decryption-screen state.
176 * Prudently disable lockscreen.
177 */
178 public static final boolean CORE_APPS_ONLY;
179 static {
180 try {
181 CORE_APPS_ONLY = IPackageManager.Stub.asInterface(
182 ServiceManager.getService("package")).isOnlyCoreApps();
183 } catch (RemoteException e) {
184 throw e.rethrowFromSystemServer();
185 }
186 }
187
Jim Millerdcb3d842012-08-23 19:18:12 -0700188 private static KeyguardUpdateMonitor sInstance;
189
Jim Millerbbf1a742012-07-17 18:30:30 -0700190 private final Context mContext;
Jim Miller52a61332014-11-12 19:29:51 -0800191 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
Etan Cohen47051d82015-07-06 16:19:04 -0700192 HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700193
Jim Millerbbf1a742012-07-17 18:30:30 -0700194 private int mRingMode;
195 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400196 private boolean mKeyguardIsVisible;
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700197 private boolean mKeyguardGoingAway;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700198 private boolean mGoingToSleep;
Adrian Roosb6011622014-05-14 15:52:53 +0200199 private boolean mBouncer;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800200 private boolean mBootCompleted;
Jorim Jaggi031f7952016-09-01 16:39:26 -0700201 private boolean mNeedsSlowUnlockTransition;
Jorim Jaggid11d1a92016-08-16 16:02:32 -0700202 private boolean mHasLockscreenWallpaper;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700203 private boolean mAssistantVisible;
204 private boolean mKeyguardOccluded;
Jim Millerbbf1a742012-07-17 18:30:30 -0700205
Jim Millerdcb3d842012-08-23 19:18:12 -0700206 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700207 private boolean mDeviceProvisioned;
208
Jim Millerdcb3d842012-08-23 19:18:12 -0700209 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700210 private BatteryStatus mBatteryStatus;
211
Jim Millerdcb3d842012-08-23 19:18:12 -0700212 // Password attempts
Jorim Jaggi9f743032015-05-04 15:22:40 -0700213 private SparseIntArray mFailedAttempts = new SparseIntArray();
Brian Colonnacc4104f2012-10-09 17:50:46 -0400214
Rakesh Iyera7aa4d62016-01-19 17:27:23 -0800215 private final StrongAuthTracker mStrongAuthTracker;
Jim Millerbbf1a742012-07-17 18:30:30 -0700216
Jim Miller6212cc02012-09-05 17:35:31 -0700217 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700218 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800219 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700220
Brian Colonnaa5239892013-04-15 11:45:40 -0400221 private boolean mSwitchingUser;
222
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700223 private boolean mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -0700224 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800225 private SubscriptionManager mSubscriptionManager;
226 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700227 private TrustManager mTrustManager;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700228 private UserManager mUserManager;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700229 private int mFingerprintRunningState = FINGERPRINT_STATE_STOPPED;
Michal Karpinskic52f8672016-11-18 11:32:45 +0000230 private LockPatternUtils mLockPatternUtils;
Kevin Chyn36778ff2017-09-07 19:55:38 -0700231 private final IDreamManager mDreamManager;
232 private boolean mIsDreaming;
Alex Chauff7653d2018-02-01 17:18:08 +0000233 private final DevicePolicyManager mDevicePolicyManager;
234 private boolean mLogoutEnabled;
Jim Miller20daffd2013-10-07 14:59:53 -0700235
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700236 /**
237 * Short delay before restarting fingerprint authentication after a successful try
238 * This should be slightly longer than the time between onFingerprintAuthenticated and
239 * setKeyguardGoingAway(true).
240 */
241 private static final int FINGERPRINT_CONTINUE_DELAY_MS = 500;
242
Kevin Chyn0c45b072017-04-24 16:27:11 -0700243 // If FP daemon dies, keyguard should retry after a short delay
244 private int mHardwareUnavailableRetryCount = 0;
245 private static final int HW_UNAVAILABLE_TIMEOUT = 3000; // ms
246 private static final int HW_UNAVAILABLE_RETRY_MAX = 3;
247
Jason Monk7bb59302018-05-10 19:38:18 -0700248 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700249 @Override
250 public void handleMessage(Message msg) {
251 switch (msg.what) {
252 case MSG_TIME_UPDATE:
253 handleTimeUpdate();
254 break;
255 case MSG_BATTERY_UPDATE:
256 handleBatteryUpdate((BatteryStatus) msg.obj);
257 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700258 case MSG_SIM_STATE_CHANGE:
Jim Miller52a61332014-11-12 19:29:51 -0800259 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700260 break;
261 case MSG_RINGER_MODE_CHANGED:
262 handleRingerModeChange(msg.arg1);
263 break;
264 case MSG_PHONE_STATE_CHANGED:
Adrian Roosb6011622014-05-14 15:52:53 +0200265 handlePhoneStateChanged((String) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700266 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700267 case MSG_DEVICE_PROVISIONED:
268 handleDeviceProvisioned();
269 break;
270 case MSG_DPM_STATE_CHANGED:
271 handleDevicePolicyManagerStateChanged();
272 break;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500273 case MSG_USER_SWITCHING:
Adrian Roosb6011622014-05-14 15:52:53 +0200274 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
Chris Wrenf41c61b2012-11-29 15:19:54 -0500275 break;
276 case MSG_USER_SWITCH_COMPLETE:
277 handleUserSwitchComplete(msg.arg1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700278 break;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700279 case MSG_KEYGUARD_RESET:
280 handleKeyguardReset();
281 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200282 case MSG_KEYGUARD_BOUNCER_CHANGED:
283 handleKeyguardBouncerChanged(msg.arg1);
284 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800285 case MSG_BOOT_COMPLETED:
286 handleBootCompleted();
287 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700288 case MSG_USER_INFO_CHANGED:
289 handleUserInfoChanged(msg.arg1);
290 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400291 case MSG_REPORT_EMERGENCY_CALL_ACTION:
292 handleReportEmergencyCallAction();
293 break;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700294 case MSG_STARTED_GOING_TO_SLEEP:
295 handleStartedGoingToSleep(msg.arg1);
296 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700297 case MSG_FINISHED_GOING_TO_SLEEP:
298 handleFinishedGoingToSleep(msg.arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700299 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700300 case MSG_STARTED_WAKING_UP:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700301 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_STARTED_WAKING_UP");
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700302 handleStartedWakingUp();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700303 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -0700304 break;
Jorim Jaggie7b12522014-08-06 16:41:21 +0200305 case MSG_FACE_UNLOCK_STATE_CHANGED:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700306 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_FACE_UNLOCK_STATE_CHANGED");
Adrian Roos4a410172014-08-20 17:41:44 +0200307 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
Nick Desaulniers1d396752016-07-25 15:05:33 -0700308 Trace.endSection();
Jorim Jaggie7b12522014-08-06 16:41:21 +0200309 break;
Jim Miller52a61332014-11-12 19:29:51 -0800310 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
311 handleSimSubscriptionInfoChanged();
312 break;
Jason Monk052082c2015-06-11 11:35:23 -0400313 case MSG_AIRPLANE_MODE_CHANGED:
314 handleAirplaneModeChanged();
315 break;
Etan Cohen47051d82015-07-06 16:19:04 -0700316 case MSG_SERVICE_STATE_CHANGE:
317 handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
318 break;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700319 case MSG_SCREEN_TURNED_ON:
320 handleScreenTurnedOn();
321 break;
322 case MSG_SCREEN_TURNED_OFF:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700323 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_SCREEN_TURNED_ON");
Jorim Jaggif1518da2015-07-30 11:56:36 -0700324 handleScreenTurnedOff();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700325 Trace.endSection();
Jorim Jaggif1518da2015-07-30 11:56:36 -0700326 break;
Selim Cinek99415392016-09-09 14:58:41 -0700327 case MSG_DREAMING_STATE_CHANGED:
328 handleDreamingStateChanged(msg.arg1);
329 break;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700330 case MSG_USER_UNLOCKED:
331 handleUserUnlocked();
332 break;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700333 case MSG_ASSISTANT_STACK_CHANGED:
334 mAssistantVisible = (boolean)msg.obj;
335 updateFingerprintListeningState();
336 break;
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700337 case MSG_FINGERPRINT_AUTHENTICATION_CONTINUE:
338 updateFingerprintListeningState();
339 break;
Alex Chauff7653d2018-02-01 17:18:08 +0000340 case MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED:
341 updateLogoutEnabled();
342 break;
Jason Monk7bb59302018-05-10 19:38:18 -0700343 default:
344 super.handleMessage(msg);
345 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700346 }
347 }
348 };
349
Wink Savilled09c4ca2014-11-22 10:08:16 -0800350 private OnSubscriptionsChangedListener mSubscriptionListener =
351 new OnSubscriptionsChangedListener() {
Jim Miller52a61332014-11-12 19:29:51 -0800352 @Override
Wink Savilled09c4ca2014-11-22 10:08:16 -0800353 public void onSubscriptionsChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800354 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
355 }
356 };
357
Adrian Roos46842d92014-03-27 14:58:03 +0100358 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200359 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Jim Miller9f0753f2015-03-23 23:59:22 -0700360 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200361 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100362
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700363 private static int sCurrentUser;
Selim Cinekbbe19242017-12-08 15:42:08 -0800364 private Runnable mUpdateFingerprintListeningState = this::updateFingerprintListeningState;
Adrian Roos30a2ae62018-04-25 19:09:50 +0200365 private static boolean sDisableHandlerCheckForTesting;
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700366
367 public synchronized static void setCurrentUser(int currentUser) {
368 sCurrentUser = currentUser;
369 }
370
371 public synchronized static int getCurrentUser() {
372 return sCurrentUser;
373 }
374
Adrian Roos46842d92014-03-27 14:58:03 +0100375 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700376 public void onTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200377 checkIsHandlerThread();
Adrian Roos46842d92014-03-27 14:58:03 +0100378 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200379 for (int i = 0; i < mCallbacks.size(); i++) {
380 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
381 if (cb != null) {
382 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700383 if (enabled && flags != 0) {
384 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200385 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200386 }
387 }
Adrian Roos46842d92014-03-27 14:58:03 +0100388 }
389
Lucas Dupinef886542018-01-03 16:03:07 -0800390 @Override
391 public void onTrustError(CharSequence message) {
392 dispatchErrorMessage(message);
393 }
394
Adrian Roos30a2ae62018-04-25 19:09:50 +0200395 private void handleSimSubscriptionInfoChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800396 if (DEBUG_SIM_STATES) {
397 Log.v(TAG, "onSubscriptionInfoChanged()");
Wink Savilled09c4ca2014-11-22 10:08:16 -0800398 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
399 if (sil != null) {
400 for (SubscriptionInfo subInfo : sil) {
401 Log.v(TAG, "SubInfo:" + subInfo);
402 }
403 } else {
404 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800405 }
406 }
407 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
408
409 // Hack level over 9000: Because the subscription id is not yet valid when we see the
410 // first update in handleSimStateChange, we need to force refresh all all SIM states
411 // so the subscription id for them is consistent.
Richard Choue0381b82018-04-24 03:48:59 +0000412 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
413 for (int i = 0; i < subscriptionInfos.size(); i++) {
414 SubscriptionInfo info = subscriptionInfos.get(i);
415 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
416 if (changed) {
417 changedSubscriptions.add(info);
418 }
419 }
420 for (int i = 0; i < changedSubscriptions.size(); i++) {
421 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800422 for (int j = 0; j < mCallbacks.size(); j++) {
423 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
424 if (cb != null) {
425 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
426 }
427 }
428 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500429 for (int j = 0; j < mCallbacks.size(); j++) {
430 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
431 if (cb != null) {
432 cb.onRefreshCarrierInfo();
433 }
434 }
Jim Miller52a61332014-11-12 19:29:51 -0800435 }
436
Jason Monk052082c2015-06-11 11:35:23 -0400437 private void handleAirplaneModeChanged() {
438 for (int j = 0; j < mCallbacks.size(); j++) {
439 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
440 if (cb != null) {
441 cb.onRefreshCarrierInfo();
442 }
443 }
444 }
445
Wink Savilled09c4ca2014-11-22 10:08:16 -0800446 /** @return List of SubscriptionInfo records, maybe empty but never null */
Adrian Roos316bf542016-08-23 17:53:07 +0200447 public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800448 List<SubscriptionInfo> sil = mSubscriptionInfo;
449 if (sil == null || forceReload) {
450 sil = mSubscriptionManager.getActiveSubscriptionInfoList();
451 }
452 if (sil == null) {
453 // getActiveSubscriptionInfoList was null callers expect an empty list.
454 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
455 } else {
456 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800457 }
458 return mSubscriptionInfo;
459 }
460
Adrian Roos7861c662014-07-25 15:37:28 +0200461 @Override
462 public void onTrustManagedChanged(boolean managed, int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200463 checkIsHandlerThread();
Adrian Roos7861c662014-07-25 15:37:28 +0200464 mUserTrustIsManaged.put(userId, managed);
465
466 for (int i = 0; i < mCallbacks.size(); i++) {
467 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
468 if (cb != null) {
469 cb.onTrustManagedChanged(userId);
470 }
471 }
472 }
473
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700474 /**
475 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is goingAway
476 * @param goingAway
477 */
478 public void setKeyguardGoingAway(boolean goingAway) {
479 mKeyguardGoingAway = goingAway;
Kevin Chyne22f1342017-09-26 10:03:38 -0700480 updateFingerprintListeningState();
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700481 }
482
Kevin Chyn2fefd462017-04-28 12:18:19 -0700483 /**
484 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is occluded
485 * @param occluded
486 */
487 public void setKeyguardOccluded(boolean occluded) {
488 mKeyguardOccluded = occluded;
489 updateFingerprintListeningState();
490 }
491
Kevin Chyn36778ff2017-09-07 19:55:38 -0700492 /**
493 * @return a cached version of DreamManager.isDreaming()
494 */
495 public boolean isDreaming() {
496 return mIsDreaming;
497 }
498
499 /**
500 * If the device is dreaming, awakens the device
501 */
502 public void awakenFromDream() {
503 if (mIsDreaming && mDreamManager != null) {
504 try {
505 mDreamManager.awaken();
506 } catch (RemoteException e) {
507 Log.e(TAG, "Unable to awaken from dream");
508 }
509 }
510 }
511
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700512 private void onFingerprintAuthenticated(int userId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700513 Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
Jim Miller9f0753f2015-03-23 23:59:22 -0700514 mUserFingerprintAuthenticated.put(userId, true);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700515 // Update/refresh trust state only if user can skip bouncer
516 if (getUserCanSkipBouncer(userId)) {
517 mTrustManager.unlockedByFingerprintForUser(userId);
518 }
Kevin Chyn625a0142017-04-10 14:53:59 -0700519 // Don't send cancel if authentication succeeds
520 mFingerprintCancelSignal = null;
Jim Millerf41fc962014-06-18 16:33:51 -0700521 for (int i = 0; i < mCallbacks.size(); i++) {
522 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
523 if (cb != null) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700524 cb.onFingerprintAuthenticated(userId);
Jim Millerf41fc962014-06-18 16:33:51 -0700525 }
526 }
Kevin Chyn2fefd462017-04-28 12:18:19 -0700527
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700528 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_FINGERPRINT_AUTHENTICATION_CONTINUE),
529 FINGERPRINT_CONTINUE_DELAY_MS);
530
Kevin Chyn2fefd462017-04-28 12:18:19 -0700531 // Only authenticate fingerprint once when assistant is visible
532 mAssistantVisible = false;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700533
Nick Desaulniers1d396752016-07-25 15:05:33 -0700534 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700535 }
536
Jim Millerce7eb6d2015-04-03 19:29:13 -0700537 private void handleFingerprintAuthFailed() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700538 for (int i = 0; i < mCallbacks.size(); i++) {
539 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
540 if (cb != null) {
541 cb.onFingerprintAuthFailed();
542 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700543 }
Jim Millerce7eb6d2015-04-03 19:29:13 -0700544 handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized));
545 }
Jim Millerf41fc962014-06-18 16:33:51 -0700546
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700547 private void handleFingerprintAcquired(int acquireInfo) {
548 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
549 return;
550 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700551 for (int i = 0; i < mCallbacks.size(); i++) {
552 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
553 if (cb != null) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700554 cb.onFingerprintAcquired();
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700555 }
556 }
557 }
558
Jim Miller837fa7e2016-08-08 20:16:22 -0700559 private void handleFingerprintAuthenticated(int authUserId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700560 Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
Jim Millerf41fc962014-06-18 16:33:51 -0700561 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700562 final int userId;
563 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800564 userId = ActivityManager.getService().getCurrentUser().id;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700565 } catch (RemoteException e) {
566 Log.e(TAG, "Failed to get current user id: ", e);
567 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700568 }
Jim Miller837fa7e2016-08-08 20:16:22 -0700569 if (userId != authUserId) {
570 Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId);
571 return;
572 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700573 if (isFingerprintDisabled(userId)) {
574 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
575 return;
576 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700577 onFingerprintAuthenticated(userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700578 } finally {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700579 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
Jim Millerf41fc962014-06-18 16:33:51 -0700580 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700581 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700582 }
583
Jim Miller9f0753f2015-03-23 23:59:22 -0700584 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700585 for (int i = 0; i < mCallbacks.size(); i++) {
586 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
587 if (cb != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700588 cb.onFingerprintHelp(msgId, helpString);
589 }
590 }
591 }
592
Kevin Chyn0c45b072017-04-24 16:27:11 -0700593 private Runnable mRetryFingerprintAuthentication = new Runnable() {
594 @Override
595 public void run() {
596 Log.w(TAG, "Retrying fingerprint after HW unavailable, attempt " +
597 mHardwareUnavailableRetryCount);
598 updateFingerprintListeningState();
599 }
600 };
601
Jim Miller9f0753f2015-03-23 23:59:22 -0700602 private void handleFingerprintError(int msgId, String errString) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700603 if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
604 && mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
605 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
606 startListeningForFingerprint();
607 } else {
608 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
609 }
Kevin Chyn0c45b072017-04-24 16:27:11 -0700610
611 if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) {
612 if (mHardwareUnavailableRetryCount < HW_UNAVAILABLE_RETRY_MAX) {
613 mHardwareUnavailableRetryCount++;
614 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
615 mHandler.postDelayed(mRetryFingerprintAuthentication, HW_UNAVAILABLE_TIMEOUT);
616 }
617 }
618
Kevin Chyndf9d33e2017-05-03 21:40:12 -0700619 if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
620 mLockPatternUtils.requireStrongAuth(
621 LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
622 getCurrentUser());
623 }
624
Jim Miller9f0753f2015-03-23 23:59:22 -0700625 for (int i = 0; i < mCallbacks.size(); i++) {
626 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
627 if (cb != null) {
628 cb.onFingerprintError(msgId, errString);
Jim Millerf41fc962014-06-18 16:33:51 -0700629 }
630 }
631 }
632
Jorim Jaggi3a464782015-08-28 16:59:13 -0700633 private void handleFingerprintLockoutReset() {
634 updateFingerprintListeningState();
635 }
636
Jorim Jaggi86bed402015-08-20 18:20:02 -0700637 private void setFingerprintRunningState(int fingerprintRunningState) {
638 boolean wasRunning = mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
639 boolean isRunning = fingerprintRunningState == FINGERPRINT_STATE_RUNNING;
640 mFingerprintRunningState = fingerprintRunningState;
641
642 // Clients of KeyguardUpdateMonitor don't care about the internal state about the
643 // asynchronousness of the cancel cycle. So only notify them if the actualy running state
644 // has changed.
645 if (wasRunning != isRunning) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700646 notifyFingerprintRunningStateChanged();
647 }
648 }
649
650 private void notifyFingerprintRunningStateChanged() {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200651 checkIsHandlerThread();
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700652 for (int i = 0; i < mCallbacks.size(); i++) {
653 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
654 if (cb != null) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700655 cb.onFingerprintRunningStateChanged(isFingerprintDetectionRunning());
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700656 }
657 }
658 }
Adrian Roos4a410172014-08-20 17:41:44 +0200659 private void handleFaceUnlockStateChanged(boolean running, int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200660 checkIsHandlerThread();
Adrian Roos4a410172014-08-20 17:41:44 +0200661 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200662 for (int i = 0; i < mCallbacks.size(); i++) {
663 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
664 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200665 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200666 }
667 }
668 }
669
Adrian Roos4a410172014-08-20 17:41:44 +0200670 public boolean isFaceUnlockRunning(int userId) {
671 return mUserFaceUnlockRunning.get(userId);
672 }
673
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700674 public boolean isFingerprintDetectionRunning() {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700675 return mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700676 }
677
Jim Miller50e62182014-04-23 17:25:00 -0700678 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100679 // Don't allow trust agent if device is secured with a SIM PIN. This is here
680 // mainly because there's no other way to prompt the user to enter their SIM PIN
681 // once they get past the keyguard screen.
682 final boolean disabledBySimPin = isSimPinSecure();
683 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700684 }
685
Jim Miller06e34502014-07-17 14:46:05 -0700686 private boolean isFingerprintDisabled(int userId) {
687 final DevicePolicyManager dpm =
688 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
689 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
Adrian Roos733b6632015-08-21 14:32:35 -0700690 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0
691 || isSimPinSecure();
Jim Miller06e34502014-07-17 14:46:05 -0700692 }
693
Selim Cineke8bae622015-07-15 13:24:06 -0700694 public boolean getUserCanSkipBouncer(int userId) {
Selim Cinek1fcafc42015-07-20 14:39:25 -0700695 return getUserHasTrust(userId) || (mUserFingerprintAuthenticated.get(userId)
696 && isUnlockingWithFingerprintAllowed());
Selim Cineke8bae622015-07-15 13:24:06 -0700697 }
698
Adrian Roos46842d92014-03-27 14:58:03 +0100699 public boolean getUserHasTrust(int userId) {
Selim Cineke8bae622015-07-15 13:24:06 -0700700 return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100701 }
702
Adrian Roos7861c662014-07-25 15:37:28 +0200703 public boolean getUserTrustIsManaged(int userId) {
704 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
705 }
706
Selim Cinek1fcafc42015-07-20 14:39:25 -0700707 public boolean isUnlockingWithFingerprintAllowed() {
Michal Karpinskic52f8672016-11-18 11:32:45 +0000708 return mStrongAuthTracker.isUnlockingWithFingerprintAllowed();
Adrian Roosb5e47222015-08-14 15:53:06 -0700709 }
710
Lucas Dupin16013822018-05-17 18:00:16 -0700711 public boolean isUserInLockdown(int userId) {
712 return mStrongAuthTracker.getStrongAuthForUser(userId)
713 == LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
714 }
715
Jorim Jaggi031f7952016-09-01 16:39:26 -0700716 public boolean needsSlowUnlockTransition() {
717 return mNeedsSlowUnlockTransition;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700718 }
719
Adrian Roosb5e47222015-08-14 15:53:06 -0700720 public StrongAuthTracker getStrongAuthTracker() {
721 return mStrongAuthTracker;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700722 }
723
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700724 private void notifyStrongAuthStateChanged(int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200725 checkIsHandlerThread();
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700726 for (int i = 0; i < mCallbacks.size(); i++) {
727 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
728 if (cb != null) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700729 cb.onStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700730 }
731 }
Selim Cinek1fcafc42015-07-20 14:39:25 -0700732 }
733
Adrian Roos91ba3072017-02-14 16:50:46 +0100734 public boolean isScreenOn() {
735 return mScreenOn;
736 }
737
Lucas Dupinef886542018-01-03 16:03:07 -0800738 private void dispatchErrorMessage(CharSequence message) {
739 for (int i = 0; i < mCallbacks.size(); i++) {
740 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
741 if (cb != null) {
742 cb.onTrustAgentErrorMessage(message);
743 }
744 }
745 }
746
Jim Miller8f09fd22013-03-14 19:04:28 -0700747 static class DisplayClientState {
748 public int clientGeneration;
749 public boolean clearing;
750 public PendingIntent intent;
751 public int playbackState;
752 public long playbackEventTime;
753 }
754
755 private DisplayClientState mDisplayClientState = new DisplayClientState();
756
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800757 @VisibleForTesting
Lucas Dupin7ff82b02018-05-16 12:14:10 -0700758 protected final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
Jim Millerbbf1a742012-07-17 18:30:30 -0700759
Jim Millerd72d5ac2015-09-29 18:55:32 -0700760 @Override
Jim Millerbbf1a742012-07-17 18:30:30 -0700761 public void onReceive(Context context, Intent intent) {
762 final String action = intent.getAction();
763 if (DEBUG) Log.d(TAG, "received broadcast " + action);
764
765 if (Intent.ACTION_TIME_TICK.equals(action)
766 || Intent.ACTION_TIME_CHANGED.equals(action)
Adrian Roos48c796c2014-09-01 14:59:23 +0200767 || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700768 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Jim Millerbbf1a742012-07-17 18:30:30 -0700769 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
770 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
771 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
772 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
773 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
Adrian Roos0c859ae2015-11-23 16:47:50 -0800774
775 final int maxChargingMicroAmp = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
776 int maxChargingMicroVolt = intent.getIntExtra(EXTRA_MAX_CHARGING_VOLTAGE, -1);
777 final int maxChargingMicroWatt;
778
779 if (maxChargingMicroVolt <= 0) {
780 maxChargingMicroVolt = DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT;
781 }
782 if (maxChargingMicroAmp > 0) {
783 // Calculating muW = muA * muV / (10^6 mu^2 / mu); splitting up the divisor
784 // to maintain precision equally on both factors.
785 maxChargingMicroWatt = (maxChargingMicroAmp / 1000)
786 * (maxChargingMicroVolt / 1000);
787 } else {
788 maxChargingMicroWatt = -1;
789 }
Jim Millerbbf1a742012-07-17 18:30:30 -0700790 final Message msg = mHandler.obtainMessage(
Adrian Roos7b043112015-07-10 13:00:33 -0700791 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
Adrian Roos0c859ae2015-11-23 16:47:50 -0800792 maxChargingMicroWatt));
Jim Millerbbf1a742012-07-17 18:30:30 -0700793 mHandler.sendMessage(msg);
794 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800795 // ACTION_SIM_STATE_CHANGED is rebroadcast after unlocking the device to
796 // keep compatibility with apps that aren't direct boot aware.
797 // SysUI should just ignore this broadcast because it was already received
798 // and processed previously.
799 if (intent.getBooleanExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
800 return;
801 }
Jim Miller52a61332014-11-12 19:29:51 -0800802 SimData args = SimData.fromIntent(intent);
Jim Millerbbf1a742012-07-17 18:30:30 -0700803 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -0800804 Log.v(TAG, "action " + action
805 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
806 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -0700807 }
Jim Miller52a61332014-11-12 19:29:51 -0800808 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
809 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -0700810 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
811 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
812 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
813 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
814 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
815 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Jason Monk052082c2015-06-11 11:35:23 -0400816 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
817 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800818 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700819 dispatchBootCompleted();
Etan Cohen47051d82015-07-06 16:19:04 -0700820 } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
821 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
822 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
823 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
824 if (DEBUG) {
825 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
826 + subId);
827 }
828 mHandler.sendMessage(
829 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
Alex Chauff7653d2018-02-01 17:18:08 +0000830 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
831 action)) {
832 mHandler.sendEmptyMessage(MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jim Millerbbf1a742012-07-17 18:30:30 -0700833 }
834 }
835 };
Jim Miller2de5ee82012-06-14 22:22:50 -0700836
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700837 private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
838
Jim Millerd72d5ac2015-09-29 18:55:32 -0700839 @Override
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700840 public void onReceive(Context context, Intent intent) {
841 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +0200842 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
843 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
844 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700845 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
846 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +0200847 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700848 Trace.beginSection("KeyguardUpdateMonitor.mBroadcastAllReceiver#onReceive ACTION_FACE_UNLOCK_STARTED");
Adrian Roos48c796c2014-09-01 14:59:23 +0200849 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
850 getSendingUserId()));
Nick Desaulniers1d396752016-07-25 15:05:33 -0700851 Trace.endSection();
Adrian Roos48c796c2014-09-01 14:59:23 +0200852 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
853 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
854 getSendingUserId()));
855 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
856 .equals(action)) {
857 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -0700858 } else if (ACTION_USER_UNLOCKED.equals(action)) {
859 mHandler.sendEmptyMessage(MSG_USER_UNLOCKED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700860 }
861 }
862 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700863
Jorim Jaggi3a464782015-08-28 16:59:13 -0700864 private final FingerprintManager.LockoutResetCallback mLockoutResetCallback
865 = new FingerprintManager.LockoutResetCallback() {
866 @Override
867 public void onLockoutReset() {
868 handleFingerprintLockoutReset();
869 }
870 };
871
Jim Miller9f0753f2015-03-23 23:59:22 -0700872 private FingerprintManager.AuthenticationCallback mAuthenticationCallback
873 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -0700874
875 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -0700876 public void onAuthenticationFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700877 handleFingerprintAuthFailed();
Jim Millerce7eb6d2015-04-03 19:29:13 -0700878 };
879
880 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700881 public void onAuthenticationSucceeded(AuthenticationResult result) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700882 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
Jim Miller837fa7e2016-08-08 20:16:22 -0700883 handleFingerprintAuthenticated(result.getUserId());
Nick Desaulniers1d396752016-07-25 15:05:33 -0700884 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700885 }
886
887 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700888 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700889 handleFingerprintHelp(helpMsgId, helpString.toString());
Jim Miller9f0753f2015-03-23 23:59:22 -0700890 }
891
892 @Override
893 public void onAuthenticationError(int errMsgId, CharSequence errString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700894 handleFingerprintError(errMsgId, errString.toString());
895 }
896
897 @Override
898 public void onAuthenticationAcquired(int acquireInfo) {
899 handleFingerprintAcquired(acquireInfo);
Jim Millerf41fc962014-06-18 16:33:51 -0700900 }
901 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700902 private CancellationSignal mFingerprintCancelSignal;
903 private FingerprintManager mFpm;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700904
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800905 /**
Jim Miller47088bb2009-11-24 00:40:16 -0800906 * When we receive a
907 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -0700908 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800909 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -0800910 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800911 */
Jim Miller52a61332014-11-12 19:29:51 -0800912 private static class SimData {
913 public State simState;
914 public int slotId;
915 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800916
Jim Miller52a61332014-11-12 19:29:51 -0800917 SimData(State state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -0800918 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -0800919 slotId = slot;
920 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -0800921 }
922
Jim Miller52a61332014-11-12 19:29:51 -0800923 static SimData fromIntent(Intent intent) {
924 State state;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800925 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
926 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
927 }
Wink Savillea639b312012-07-10 12:37:54 -0700928 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
Jim Miller52a61332014-11-12 19:29:51 -0800929 int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0);
930 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
Wink Savilled09c4ca2014-11-22 10:08:16 -0800931 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea639b312012-07-10 12:37:54 -0700932 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -0700933 final String absentReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700934 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -0700935
Wink Savillea639b312012-07-10 12:37:54 -0700936 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -0700937 absentReason)) {
Wink Savillea639b312012-07-10 12:37:54 -0700938 state = IccCardConstants.State.PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -0700939 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700940 state = IccCardConstants.State.ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -0700941 }
Wink Savillea639b312012-07-10 12:37:54 -0700942 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
943 state = IccCardConstants.State.READY;
944 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800945 final String lockedReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700946 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
947 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
948 state = IccCardConstants.State.PIN_REQUIRED;
949 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
950 state = IccCardConstants.State.PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800951 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700952 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800953 }
Wink Savillea639b312012-07-10 12:37:54 -0700954 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
955 state = IccCardConstants.State.NETWORK_LOCKED;
Wileen Chiu6b8b22e2014-10-29 22:48:21 +0530956 } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
957 state = IccCardConstants.State.CARD_IO_ERROR;
Jim Miller109f1fd2012-09-19 20:44:16 -0700958 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
959 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
960 // This is required because telephony doesn't return to "READY" after
961 // these state transitions. See bug 7197471.
962 state = IccCardConstants.State.READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800963 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700964 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800965 }
Jim Miller52a61332014-11-12 19:29:51 -0800966 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800967 }
968
Jim Millerd72d5ac2015-09-29 18:55:32 -0700969 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800970 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -0800971 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800972 }
973 }
974
Adrian Roos12c1ef52014-06-04 13:54:08 +0200975 public static class BatteryStatus {
Adrian Roos7b043112015-07-10 13:00:33 -0700976 public static final int CHARGING_UNKNOWN = -1;
977 public static final int CHARGING_SLOWLY = 0;
978 public static final int CHARGING_REGULAR = 1;
979 public static final int CHARGING_FAST = 2;
980
Jim Miller16464b82011-10-20 21:10:13 -0700981 public final int status;
982 public final int level;
983 public final int plugged;
984 public final int health;
Adrian Roos0c859ae2015-11-23 16:47:50 -0800985 public final int maxChargingWattage;
986 public BatteryStatus(int status, int level, int plugged, int health,
987 int maxChargingWattage) {
Jim Miller16464b82011-10-20 21:10:13 -0700988 this.status = status;
989 this.level = level;
990 this.plugged = plugged;
991 this.health = health;
Adrian Roos0c859ae2015-11-23 16:47:50 -0800992 this.maxChargingWattage = maxChargingWattage;
Jim Miller16464b82011-10-20 21:10:13 -0700993 }
994
Jim Millerbbf1a742012-07-17 18:30:30 -0700995 /**
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700996 * Determine whether the device is plugged in (USB, power, or wireless).
Jim Millerbbf1a742012-07-17 18:30:30 -0700997 * @return true if the device is plugged in.
998 */
Adrian Roosad3bc7f2014-10-30 18:29:38 +0100999 public boolean isPluggedIn() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001000 return plugged == BatteryManager.BATTERY_PLUGGED_AC
Brian Muramatsua92a01b2012-09-05 21:54:39 -07001001 || plugged == BatteryManager.BATTERY_PLUGGED_USB
1002 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Jim Millerbbf1a742012-07-17 18:30:30 -07001003 }
1004
1005 /**
Beverly2034c832018-03-19 11:18:51 -04001006 * Determine whether the device is plugged in (USB, power).
1007 * @return true if the device is plugged in wired (as opposed to wireless)
1008 */
1009 public boolean isPluggedInWired() {
1010 return plugged == BatteryManager.BATTERY_PLUGGED_AC
1011 || plugged == BatteryManager.BATTERY_PLUGGED_USB;
1012 }
1013
1014 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001015 * Whether or not the device is charged. Note that some devices never return 100% for
1016 * battery level, so this allows either battery level or status to determine if the
1017 * battery is charged.
1018 * @return true if the device is charged
1019 */
1020 public boolean isCharged() {
1021 return status == BATTERY_STATUS_FULL || level >= 100;
1022 }
1023
1024 /**
1025 * Whether battery is low and needs to be charged.
1026 * @return true if battery is low
1027 */
1028 public boolean isBatteryLow() {
1029 return level < LOW_BATTERY_THRESHOLD;
1030 }
1031
Adrian Roos7b043112015-07-10 13:00:33 -07001032 public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
Adrian Roos0c859ae2015-11-23 16:47:50 -08001033 return maxChargingWattage <= 0 ? CHARGING_UNKNOWN :
1034 maxChargingWattage < slowThreshold ? CHARGING_SLOWLY :
1035 maxChargingWattage > fastThreshold ? CHARGING_FAST :
Adrian Roos7b043112015-07-10 13:00:33 -07001036 CHARGING_REGULAR;
1037 }
Lucas Dupin3fcdd472018-01-19 19:06:45 -08001038
1039 @Override
1040 public String toString() {
1041 return "BatteryStatus{status=" + status + ",level=" + level + ",plugged=" + plugged
1042 + ",health=" + health + ",maxChargingWattage=" + maxChargingWattage + "}";
1043 }
Jim Miller16464b82011-10-20 21:10:13 -07001044 }
1045
Adrian Roosb5e47222015-08-14 15:53:06 -07001046 public class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001047 public StrongAuthTracker(Context context) {
1048 super(context);
1049 }
Adrian Roosb5e47222015-08-14 15:53:06 -07001050
1051 public boolean isUnlockingWithFingerprintAllowed() {
1052 int userId = getCurrentUser();
1053 return isFingerprintAllowedForUser(userId);
1054 }
1055
1056 public boolean hasUserAuthenticatedSinceBoot() {
1057 int userId = getCurrentUser();
1058 return (getStrongAuthForUser(userId)
1059 & STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
1060 }
1061
1062 @Override
1063 public void onStrongAuthRequiredChanged(int userId) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -07001064 notifyStrongAuthStateChanged(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -07001065 }
1066 }
1067
Jim Millerdcb3d842012-08-23 19:18:12 -07001068 public static KeyguardUpdateMonitor getInstance(Context context) {
1069 if (sInstance == null) {
1070 sInstance = new KeyguardUpdateMonitor(context);
1071 }
1072 return sInstance;
1073 }
1074
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001075 protected void handleStartedWakingUp() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001076 Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
Jorim Jaggi864e64b2015-05-20 14:13:23 -07001077 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001078 final int count = mCallbacks.size();
1079 for (int i = 0; i < count; i++) {
1080 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1081 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001082 cb.onStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -07001083 }
1084 }
Nick Desaulniers1d396752016-07-25 15:05:33 -07001085 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -07001086 }
1087
Jorim Jaggi95e40382015-09-16 15:53:42 -07001088 protected void handleStartedGoingToSleep(int arg1) {
Jim Millerf41fc962014-06-18 16:33:51 -07001089 clearFingerprintRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -07001090 final int count = mCallbacks.size();
1091 for (int i = 0; i < count; i++) {
1092 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1093 if (cb != null) {
Jorim Jaggi95e40382015-09-16 15:53:42 -07001094 cb.onStartedGoingToSleep(arg1);
1095 }
1096 }
1097 mGoingToSleep = true;
Jorim Jaggi95e40382015-09-16 15:53:42 -07001098 updateFingerprintListeningState();
1099 }
1100
1101 protected void handleFinishedGoingToSleep(int arg1) {
1102 mGoingToSleep = false;
1103 final int count = mCallbacks.size();
1104 for (int i = 0; i < count; i++) {
1105 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1106 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001107 cb.onFinishedGoingToSleep(arg1);
Jim Miller20daffd2013-10-07 14:59:53 -07001108 }
1109 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001110 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001111 }
1112
Jorim Jaggif1518da2015-07-30 11:56:36 -07001113 private void handleScreenTurnedOn() {
1114 final int count = mCallbacks.size();
1115 for (int i = 0; i < count; i++) {
1116 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1117 if (cb != null) {
1118 cb.onScreenTurnedOn();
1119 }
1120 }
1121 }
1122
1123 private void handleScreenTurnedOff() {
Kevin Chyn0c45b072017-04-24 16:27:11 -07001124 mHardwareUnavailableRetryCount = 0;
Jorim Jaggif1518da2015-07-30 11:56:36 -07001125 final int count = mCallbacks.size();
1126 for (int i = 0; i < count; i++) {
1127 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1128 if (cb != null) {
1129 cb.onScreenTurnedOff();
1130 }
1131 }
1132 }
1133
Selim Cinek99415392016-09-09 14:58:41 -07001134 private void handleDreamingStateChanged(int dreamStart) {
1135 final int count = mCallbacks.size();
Kevin Chyn36778ff2017-09-07 19:55:38 -07001136 mIsDreaming = dreamStart == 1;
Selim Cinek99415392016-09-09 14:58:41 -07001137 for (int i = 0; i < count; i++) {
1138 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1139 if (cb != null) {
Kevin Chyn36778ff2017-09-07 19:55:38 -07001140 cb.onDreamingStateChanged(mIsDreaming);
Selim Cinek99415392016-09-09 14:58:41 -07001141 }
1142 }
Kevin Chyn20a68dc2017-09-21 11:41:01 -07001143 updateFingerprintListeningState();
Selim Cinek99415392016-09-09 14:58:41 -07001144 }
1145
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001146 private void handleUserInfoChanged(int userId) {
1147 for (int i = 0; i < mCallbacks.size(); i++) {
1148 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1149 if (cb != null) {
1150 cb.onUserInfoChanged(userId);
1151 }
1152 }
1153 }
1154
Jorim Jaggidadafd42016-09-30 07:20:25 -07001155 private void handleUserUnlocked() {
1156 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1157 for (int i = 0; i < mCallbacks.size(); i++) {
1158 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1159 if (cb != null) {
1160 cb.onUserUnlocked();
1161 }
1162 }
1163 }
1164
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001165 @VisibleForTesting
1166 protected KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001167 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -08001168 mSubscriptionManager = SubscriptionManager.from(context);
Michael Jurkafff56142012-11-28 16:51:00 -08001169 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001170 mStrongAuthTracker = new StrongAuthTracker(context);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001171
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001172 // Since device can't be un-provisioned, we only need to register a content observer
1173 // to update mDeviceProvisioned when we are...
1174 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001175 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001176 }
Jim Miller47088bb2009-11-24 00:40:16 -08001177
Jim Millerbbf1a742012-07-17 18:30:30 -07001178 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Adrian Roos7b043112015-07-10 13:00:33 -07001179 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001180
Jim Millerbbf1a742012-07-17 18:30:30 -07001181 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001182 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001183 filter.addAction(Intent.ACTION_TIME_TICK);
1184 filter.addAction(Intent.ACTION_TIME_CHANGED);
1185 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
1186 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Jason Monk052082c2015-06-11 11:35:23 -04001187 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001188 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Etan Cohen47051d82015-07-06 16:19:04 -07001189 filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -08001190 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -08001191 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Alex Chauff7653d2018-02-01 17:18:08 +00001192 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jason Monk7bb59302018-05-10 19:38:18 -07001193 context.registerReceiver(mBroadcastReceiver, filter, null, mHandler);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001194
Adam Cohenc276e822012-11-08 13:01:08 -08001195 final IntentFilter bootCompleteFilter = new IntentFilter();
1196 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1197 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
Jason Monk7bb59302018-05-10 19:38:18 -07001198 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter, null, mHandler);
Adam Cohenc276e822012-11-08 13:01:08 -08001199
Adrian Roos48c796c2014-09-01 14:59:23 +02001200 final IntentFilter allUserFilter = new IntentFilter();
1201 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
1202 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
1203 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
1204 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
1205 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001206 allUserFilter.addAction(ACTION_USER_UNLOCKED);
Adrian Roos48c796c2014-09-01 14:59:23 +02001207 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Jason Monk7bb59302018-05-10 19:38:18 -07001208 null, mHandler);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001209
Wink Saville071743f2015-01-12 17:11:04 -08001210 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001211 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001212 ActivityManager.getService().registerUserSwitchObserver(
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001213 new UserSwitchObserver() {
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001214 @Override
1215 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001216 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001217 newUserId, 0, reply));
1218 }
1219 @Override
1220 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001221 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +02001222 newUserId, 0));
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001223 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001224 }, TAG);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001225 } catch (RemoteException e) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001226 e.rethrowAsRuntimeException();
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001227 }
Adrian Roos46842d92014-03-27 14:58:03 +01001228
Jorim Jaggi237b0612015-05-01 14:28:49 -07001229 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
1230 mTrustManager.registerTrustListener(this);
Michal Karpinskic52f8672016-11-18 11:32:45 +00001231 mLockPatternUtils = new LockPatternUtils(context);
1232 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Jim Millerf41fc962014-06-18 16:33:51 -07001233
Kevin Chyn36778ff2017-09-07 19:55:38 -07001234 mDreamManager = IDreamManager.Stub.asInterface(
1235 ServiceManager.getService(DreamService.DREAM_SERVICE));
1236
Jorim Jaggi3f124262016-11-22 13:45:17 +01001237 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
1238 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
1239 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001240 updateFingerprintListeningState();
Jorim Jaggi3a464782015-08-28 16:59:13 -07001241 if (mFpm != null) {
1242 mFpm.addLockoutResetCallback(mLockoutResetCallback);
1243 }
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001244
Winson Chung2cf6ad82017-11-09 17:36:59 -08001245 ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001246 mUserManager = context.getSystemService(UserManager.class);
Alex Chauff7653d2018-02-01 17:18:08 +00001247 mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
1248 mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
Jorim Jaggiea657062015-04-28 13:45:11 -07001249 }
1250
1251 private void updateFingerprintListeningState() {
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001252 // If this message exists, we should not authenticate again until this message is
1253 // consumed by the handler
1254 if (mHandler.hasMessages(MSG_FINGERPRINT_AUTHENTICATION_CONTINUE)) {
1255 return;
1256 }
Kevin Chyn0c45b072017-04-24 16:27:11 -07001257 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
Jorim Jaggiea657062015-04-28 13:45:11 -07001258 boolean shouldListenForFingerprint = shouldListenForFingerprint();
Jorim Jaggi86bed402015-08-20 18:20:02 -07001259 if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING && !shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001260 stopListeningForFingerprint();
Jorim Jaggi86bed402015-08-20 18:20:02 -07001261 } else if (mFingerprintRunningState != FINGERPRINT_STATE_RUNNING
1262 && shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001263 startListeningForFingerprint();
1264 }
1265 }
1266
Kevin Chyn129f60f2017-08-11 17:24:42 -07001267 private boolean shouldListenForFingerprintAssistant() {
1268 return mAssistantVisible && mKeyguardOccluded
1269 && !mUserFingerprintAuthenticated.get(getCurrentUser(), false)
1270 && !mUserHasTrust.get(getCurrentUser(), false);
1271 }
1272
Jorim Jaggiea657062015-04-28 13:45:11 -07001273 private boolean shouldListenForFingerprint() {
Kevin Chynf3b8fbd2017-05-03 22:24:31 -07001274 return (mKeyguardIsVisible || !mDeviceInteractive ||
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001275 (mBouncer && !mKeyguardGoingAway) || mGoingToSleep ||
Kevin Chyn36778ff2017-09-07 19:55:38 -07001276 shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming))
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001277 && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser())
1278 && !mKeyguardGoingAway;
Jim Miller9f0753f2015-03-23 23:59:22 -07001279 }
1280
Jim Millerce7eb6d2015-04-03 19:29:13 -07001281 private void startListeningForFingerprint() {
Jorim Jaggi86bed402015-08-20 18:20:02 -07001282 if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING) {
1283 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING_RESTARTING);
1284 return;
1285 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001286 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -07001287 int userId = ActivityManager.getCurrentUser();
Jorim Jaggi71448a72015-08-18 19:49:04 -07001288 if (isUnlockWithFingerprintPossible(userId)) {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001289 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001290 mFingerprintCancelSignal.cancel();
1291 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001292 mFingerprintCancelSignal = new CancellationSignal();
Kevin Chynaae4a152018-01-18 11:48:09 -08001293 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null,
1294 userId);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001295 setFingerprintRunningState(FINGERPRINT_STATE_RUNNING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001296 }
1297 }
1298
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001299 public boolean isUnlockWithFingerprintPossible(int userId) {
Selim Cinek3122fa82015-06-18 01:38:59 -07001300 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
1301 && mFpm.getEnrolledFingerprints(userId).size() > 0;
1302 }
1303
Jorim Jaggiea657062015-04-28 13:45:11 -07001304 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001305 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
Jorim Jaggi86bed402015-08-20 18:20:02 -07001306 if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING) {
Kevin Chyn2fefd462017-04-28 12:18:19 -07001307 if (mFingerprintCancelSignal != null) {
1308 mFingerprintCancelSignal.cancel();
1309 mFingerprintCancelSignal = null;
1310 }
Jorim Jaggi86bed402015-08-20 18:20:02 -07001311 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001312 }
Jorim Jaggi86bed402015-08-20 18:20:02 -07001313 if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
1314 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
1315 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001316 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001317
Michael Jurkafff56142012-11-28 16:51:00 -08001318 private boolean isDeviceProvisionedInSettingsDb() {
1319 return Settings.Global.getInt(mContext.getContentResolver(),
1320 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1321 }
1322
Jim Millerbbf1a742012-07-17 18:30:30 -07001323 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -08001324 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001325 @Override
1326 public void onChange(boolean selfChange) {
1327 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -08001328 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001329 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001330 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001331 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001332 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001333 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001334 };
1335
1336 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -07001337 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -08001338 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -07001339
1340 // prevent a race condition between where we check the flag and where we register the
1341 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -08001342 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001343 if (provisioned != mDeviceProvisioned) {
1344 mDeviceProvisioned = provisioned;
1345 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001346 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001347 }
1348 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001349 }
1350
Jim Millerbbf1a742012-07-17 18:30:30 -07001351 /**
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001352 * Update the state whether Keyguard currently has a lockscreen wallpaper.
1353 *
1354 * @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper.
1355 */
1356 public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001357 checkIsHandlerThread();
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001358 if (hasLockscreenWallpaper != mHasLockscreenWallpaper) {
1359 mHasLockscreenWallpaper = hasLockscreenWallpaper;
1360 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1361 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1362 if (cb != null) {
1363 cb.onHasLockscreenWallpaperChanged(hasLockscreenWallpaper);
1364 }
1365 }
1366 }
1367 }
1368
1369 /**
1370 * @return Whether Keyguard has a lockscreen wallpaper.
1371 */
1372 public boolean hasLockscreenWallpaper() {
1373 return mHasLockscreenWallpaper;
1374 }
1375
1376 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001377 * Handle {@link #MSG_DPM_STATE_CHANGED}
1378 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001379 private void handleDevicePolicyManagerStateChanged() {
Adrian Roos733b6632015-08-21 14:32:35 -07001380 updateFingerprintListeningState();
Jim Millerdcb3d842012-08-23 19:18:12 -07001381 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1382 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1383 if (cb != null) {
1384 cb.onDevicePolicyManagerStateChanged();
1385 }
Jim Millerb0304762012-03-13 20:01:25 -07001386 }
1387 }
1388
Jim Millerbbf1a742012-07-17 18:30:30 -07001389 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001390 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -07001391 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001392 private void handleUserSwitching(int userId, IRemoteCallback reply) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001393 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001394 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1395 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001396 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -07001397 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001398 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001399 try {
1400 reply.sendResult(null);
1401 } catch (RemoteException e) {
1402 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001403 }
1404
Jim Millerbbf1a742012-07-17 18:30:30 -07001405 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001406 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
1407 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001408 private void handleUserSwitchComplete(int userId) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001409 for (int i = 0; i < mCallbacks.size(); i++) {
1410 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1411 if (cb != null) {
1412 cb.onUserSwitchComplete(userId);
1413 }
1414 }
1415 }
1416
1417 /**
Jim Miller90873d52013-09-26 18:11:38 -07001418 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
1419 * keyguard crashes sometime after boot, then it will never receive this
1420 * broadcast and hence not handle the event. This method is ultimately called by
1421 * PhoneWindowManager in this case.
1422 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001423 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001424 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -07001425 }
1426
1427 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001428 * Handle {@link #MSG_BOOT_COMPLETED}
1429 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001430 private void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001431 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001432 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001433 for (int i = 0; i < mCallbacks.size(); i++) {
1434 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1435 if (cb != null) {
1436 cb.onBootCompleted();
1437 }
1438 }
1439 }
1440
1441 /**
Jim Miller5ecd8112013-01-09 18:50:26 -08001442 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001443 * destroyed.
1444 */
1445 public boolean hasBootCompleted() {
1446 return mBootCompleted;
1447 }
1448
1449 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001450 * Handle {@link #MSG_DEVICE_PROVISIONED}
1451 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001452 private void handleDeviceProvisioned() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001453 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001454 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1455 if (cb != null) {
1456 cb.onDeviceProvisioned();
1457 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001458 }
Michael Jurkafff56142012-11-28 16:51:00 -08001459 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001460 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -08001461 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
1462 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001463 }
1464 }
1465
Jim Millerbbf1a742012-07-17 18:30:30 -07001466 /**
1467 * Handle {@link #MSG_PHONE_STATE_CHANGED}
1468 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001469 private void handlePhoneStateChanged(String newState) {
Jim Millerc23024d2010-02-24 15:37:00 -08001470 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001471 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
1472 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
1473 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
1474 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
1475 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
1476 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
1477 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001478 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001479 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1480 if (cb != null) {
1481 cb.onPhoneStateChanged(mPhoneState);
1482 }
Jim Millerc23024d2010-02-24 15:37:00 -08001483 }
1484 }
1485
Jim Millerbbf1a742012-07-17 18:30:30 -07001486 /**
1487 * Handle {@link #MSG_RINGER_MODE_CHANGED}
1488 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001489 private void handleRingerModeChange(int mode) {
Jim Miller47088bb2009-11-24 00:40:16 -08001490 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001491 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -07001492 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001493 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1494 if (cb != null) {
1495 cb.onRingerModeChanged(mode);
1496 }
Jim Miller47088bb2009-11-24 00:40:16 -08001497 }
1498 }
1499
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001500 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001501 * Handle {@link #MSG_TIME_UPDATE}
1502 */
1503 private void handleTimeUpdate() {
1504 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001505 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001506 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1507 if (cb != null) {
1508 cb.onTimeChanged();
1509 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001510 }
1511 }
1512
1513 /**
1514 * Handle {@link #MSG_BATTERY_UPDATE}
1515 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001516 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001517 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001518 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
1519 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07001520 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001521 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001522 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1523 if (cb != null) {
1524 cb.onRefreshBatteryInfo(status);
1525 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001526 }
1527 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001528 }
1529
1530 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001531 * Handle {@link #MSG_SIM_STATE_CHANGE}
1532 */
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001533 @VisibleForTesting
Adrian Roos30a2ae62018-04-25 19:09:50 +02001534 void handleSimStateChange(int subId, int slotId, State state) {
1535 checkIsHandlerThread();
Jim Miller52a61332014-11-12 19:29:51 -08001536 if (DEBUG_SIM_STATES) {
1537 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
1538 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001539 }
1540
Wink Savillea54bf652014-12-11 13:37:50 -08001541 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08001542 Log.w(TAG, "invalid subId in handleSimStateChange()");
1543 return;
1544 }
1545
1546 SimData data = mSimDatas.get(subId);
1547 final boolean changed;
1548 if (data == null) {
1549 data = new SimData(state, slotId, subId);
1550 mSimDatas.put(subId, data);
1551 changed = true; // no data yet; force update
1552 } else {
1553 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
1554 data.simState = state;
1555 data.subId = subId;
1556 data.slotId = slotId;
1557 }
1558 if (changed && state != State.UNKNOWN) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001559 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001560 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1561 if (cb != null) {
Jim Miller52a61332014-11-12 19:29:51 -08001562 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07001563 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001564 }
1565 }
1566 }
1567
Jim Millerbbf1a742012-07-17 18:30:30 -07001568 /**
Etan Cohen47051d82015-07-06 16:19:04 -07001569 * Handle {@link #MSG_SERVICE_STATE_CHANGE}
1570 */
1571 private void handleServiceStateChange(int subId, ServiceState serviceState) {
1572 if (DEBUG) {
1573 Log.d(TAG,
1574 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
1575 }
1576
1577 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1578 Log.w(TAG, "invalid subId in handleServiceStateChange()");
1579 return;
1580 }
1581
1582 mServiceStates.put(subId, serviceState);
1583
1584 for (int j = 0; j < mCallbacks.size(); j++) {
1585 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
1586 if (cb != null) {
1587 cb.onRefreshCarrierInfo();
1588 }
1589 }
1590 }
1591
Lucas Dupinf8463ee2018-06-11 16:18:15 -07001592 public boolean isKeyguardVisible() {
1593 return mKeyguardIsVisible;
1594 }
1595
Etan Cohen47051d82015-07-06 16:19:04 -07001596 /**
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001597 * Notifies that the visibility state of Keyguard has changed.
1598 *
1599 * <p>Needs to be called from the main thread.
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001600 */
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001601 public void onKeyguardVisibilityChanged(boolean showing) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001602 checkIsHandlerThread();
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001603 if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
1604 mKeyguardIsVisible = showing;
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001605 for (int i = 0; i < mCallbacks.size(); i++) {
1606 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1607 if (cb != null) {
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001608 cb.onKeyguardVisibilityChangedRaw(showing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001609 }
1610 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001611 updateFingerprintListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001612 }
1613
Brian Colonna7fce3802013-09-17 15:51:32 -04001614 /**
Selim Cinek1fcafc42015-07-20 14:39:25 -07001615 * Handle {@link #MSG_KEYGUARD_RESET}
1616 */
1617 private void handleKeyguardReset() {
1618 if (DEBUG) Log.d(TAG, "handleKeyguardReset");
Adrian Roosf6d51ac2015-09-02 13:26:25 -07001619 updateFingerprintListeningState();
Jorim Jaggi031f7952016-09-01 16:39:26 -07001620 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1621 }
1622
1623 private boolean resolveNeedsSlowUnlockTransition() {
1624 if (mUserManager.isUserUnlocked(getCurrentUser())) {
1625 return false;
1626 }
1627 Intent homeIntent = new Intent(Intent.ACTION_MAIN)
1628 .addCategory(Intent.CATEGORY_HOME);
1629 ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(homeIntent,
1630 0 /* flags */);
1631 return FALLBACK_HOME_COMPONENT.equals(resolveInfo.getComponentInfo().getComponentName());
Selim Cinek1fcafc42015-07-20 14:39:25 -07001632 }
1633
1634 /**
Adrian Roosb6011622014-05-14 15:52:53 +02001635 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
1636 * @see #sendKeyguardBouncerChanged(boolean)
1637 */
1638 private void handleKeyguardBouncerChanged(int bouncer) {
1639 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
1640 boolean isBouncer = (bouncer == 1);
1641 mBouncer = isBouncer;
1642 for (int i = 0; i < mCallbacks.size(); i++) {
1643 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1644 if (cb != null) {
1645 cb.onKeyguardBouncerChanged(isBouncer);
1646 }
1647 }
Jorim Jaggi3cf7eef2015-09-10 14:36:19 -07001648 updateFingerprintListeningState();
Adrian Roosb6011622014-05-14 15:52:53 +02001649 }
1650
1651 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04001652 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
1653 */
1654 private void handleReportEmergencyCallAction() {
1655 for (int i = 0; i < mCallbacks.size(); i++) {
1656 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1657 if (cb != null) {
1658 cb.onEmergencyCallAction();
1659 }
1660 }
1661 }
1662
Lucas Dupin4272f442018-01-13 22:00:35 -08001663 private boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001664 final boolean nowPluggedIn = current.isPluggedIn();
1665 final boolean wasPluggedIn = old.isPluggedIn();
Lucas Dupin4272f442018-01-13 22:00:35 -08001666 final boolean stateChangedWhilePluggedIn = wasPluggedIn && nowPluggedIn
Jim Miller16464b82011-10-20 21:10:13 -07001667 && (old.status != current.status);
1668
1669 // change in plug state is always interesting
1670 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001671 return true;
1672 }
1673
Lucas Dupin3fcdd472018-01-19 19:06:45 -08001674 // change in battery level
1675 if (old.level != current.level) {
Jim Miller16464b82011-10-20 21:10:13 -07001676 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001677 }
Adrian Roos76dc5a52015-07-21 16:20:36 -07001678
1679 // change in charging current while plugged in
Adrian Roos0c859ae2015-11-23 16:47:50 -08001680 if (nowPluggedIn && current.maxChargingWattage != old.maxChargingWattage) {
Adrian Roos76dc5a52015-07-21 16:20:36 -07001681 return true;
1682 }
1683
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001684 return false;
1685 }
1686
1687 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001688 * Remove the given observer's callback.
1689 *
Jim Miller6212cc02012-09-05 17:35:31 -07001690 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001691 */
Jim Miller6212cc02012-09-05 17:35:31 -07001692 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001693 checkIsHandlerThread();
Jim Miller6212cc02012-09-05 17:35:31 -07001694 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
1695 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1696 if (mCallbacks.get(i).get() == callback) {
1697 mCallbacks.remove(i);
1698 }
1699 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001700 }
1701
1702 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001703 * Register to receive notifications about general keyguard information
1704 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07001705 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001706 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001707 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001708 checkIsHandlerThread();
Jim Miller6212cc02012-09-05 17:35:31 -07001709 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
1710 // Prevent adding duplicate callbacks
1711 for (int i = 0; i < mCallbacks.size(); i++) {
1712 if (mCallbacks.get(i).get() == callback) {
1713 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
1714 new Exception("Called by"));
1715 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07001716 }
1717 }
Jim Miller6212cc02012-09-05 17:35:31 -07001718 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
1719 removeCallback(null); // remove unused references
1720 sendUpdates(callback);
1721 }
1722
Evan Rosky18396452016-07-27 15:19:37 -07001723 public boolean isSwitchingUser() {
1724 return mSwitchingUser;
1725 }
1726
Adrian Roos30a2ae62018-04-25 19:09:50 +02001727 @AnyThread
Evan Rosky18396452016-07-27 15:19:37 -07001728 public void setSwitchingUser(boolean switching) {
1729 mSwitchingUser = switching;
Selim Cinekbbe19242017-12-08 15:42:08 -08001730 // Since this comes in on a binder thread, we need to post if first
1731 mHandler.post(mUpdateFingerprintListeningState);
Evan Rosky18396452016-07-27 15:19:37 -07001732 }
1733
Jim Miller6212cc02012-09-05 17:35:31 -07001734 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
1735 // Notify listener of the current state
1736 callback.onRefreshBatteryInfo(mBatteryStatus);
1737 callback.onTimeChanged();
1738 callback.onRingerModeChanged(mRingMode);
1739 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05001740 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07001741 callback.onClockVisibilityChanged();
Lucas Dupin16cfe452018-02-08 13:14:50 -08001742 callback.onKeyguardVisibilityChangedRaw(mKeyguardIsVisible);
Jim Miller52a61332014-11-12 19:29:51 -08001743 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
1744 final SimData state = data.getValue();
1745 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
1746 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001747 }
1748
Selim Cinek1fcafc42015-07-20 14:39:25 -07001749 public void sendKeyguardReset() {
1750 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
1751 }
1752
Adrian Roosb6011622014-05-14 15:52:53 +02001753 /**
1754 * @see #handleKeyguardBouncerChanged(int)
1755 */
1756 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
1757 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
1758 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
1759 message.arg1 = showingBouncer ? 1 : 0;
1760 message.sendToTarget();
1761 }
1762
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001763 /**
Jim Miller90d5d462011-11-17 16:57:01 -08001764 * 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 -08001765 * have the information earlier than waiting for the intent
1766 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08001767 *
1768 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
1769 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001770 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001771 @MainThread
Jim Miller52a61332014-11-12 19:29:51 -08001772 public void reportSimUnlocked(int subId) {
1773 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
Sanket Padawe7e460252017-03-10 16:18:20 -08001774 int slotId = SubscriptionManager.getSlotIndex(subId);
Jim Miller52a61332014-11-12 19:29:51 -08001775 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001776 }
1777
Brian Colonna7fce3802013-09-17 15:51:32 -04001778 /**
1779 * Report that the emergency call button has been pressed and the emergency dialer is
1780 * about to be displayed.
1781 *
1782 * @param bypassHandler runs immediately.
1783 *
1784 * NOTE: Must be called from UI thread if bypassHandler == true.
1785 */
1786 public void reportEmergencyCallAction(boolean bypassHandler) {
1787 if (!bypassHandler) {
1788 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
1789 } else {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001790 checkIsHandlerThread();
Brian Colonna7fce3802013-09-17 15:51:32 -04001791 handleReportEmergencyCallAction();
1792 }
1793 }
1794
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001795 /**
1796 * @return Whether the device is provisioned (whether they have gone through
1797 * the setup wizard)
1798 */
1799 public boolean isDeviceProvisioned() {
1800 return mDeviceProvisioned;
1801 }
1802
Jorim Jaggi9f743032015-05-04 15:22:40 -07001803 public void clearFailedUnlockAttempts() {
1804 mFailedAttempts.delete(sCurrentUser);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001805 }
1806
Kensuke Matsui21d1bf12017-03-14 13:27:20 +09001807 public ServiceState getServiceState(int subId) {
1808 return mServiceStates.get(subId);
1809 }
1810
Xiyuan Xiace64cea2016-01-06 08:51:16 -08001811 public int getFailedUnlockAttempts(int userId) {
1812 return mFailedAttempts.get(userId, 0);
Jorim Jaggi9f743032015-05-04 15:22:40 -07001813 }
1814
Xiyuan Xiace64cea2016-01-06 08:51:16 -08001815 public void reportFailedStrongAuthUnlockAttempt(int userId) {
1816 mFailedAttempts.put(userId, getFailedUnlockAttempts(userId) + 1);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001817 }
1818
Jim Millerf41fc962014-06-18 16:33:51 -07001819 public void clearFingerprintRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07001820 mUserFingerprintAuthenticated.clear();
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001821 mTrustManager.clearAllFingerprints();
Jim Millerf41fc962014-06-18 16:33:51 -07001822 }
1823
Jim Miller52a61332014-11-12 19:29:51 -08001824 public boolean isSimPinVoiceSecure() {
1825 // TODO: only count SIMs that handle voice
1826 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07001827 }
1828
1829 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08001830 // True if any SIM is pin secure
1831 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
1832 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
1833 }
1834 return false;
1835 }
1836
Jason Monk9ff69bd2014-12-02 16:43:17 -05001837 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08001838 if (mSimDatas.containsKey(subId)) {
1839 return mSimDatas.get(subId).simState;
1840 } else {
1841 return State.UNKNOWN;
1842 }
1843 }
1844
Winson Chungaa357452017-10-31 11:35:30 -07001845 private final SysUiTaskStackChangeListener
1846 mTaskStackListener = new SysUiTaskStackChangeListener() {
Kevin Chyn2fefd462017-04-28 12:18:19 -07001847 @Override
1848 public void onTaskStackChangedBackground() {
1849 try {
1850 ActivityManager.StackInfo info = ActivityManager.getService().getStackInfo(
Wale Ogunwale68278562017-09-23 17:13:55 -07001851 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
Kevin Chyn2fefd462017-04-28 12:18:19 -07001852 if (info == null) {
1853 return;
1854 }
1855 mHandler.sendMessage(mHandler.obtainMessage(MSG_ASSISTANT_STACK_CHANGED,
1856 info.visible));
1857 } catch (RemoteException e) {
1858 Log.e(TAG, "unable to check task stack", e);
1859 }
1860 }
1861 };
1862
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001863 /**
Richard Choue0381b82018-04-24 03:48:59 +00001864 * @return true if and only if the state has changed for the specified {@code slotId}
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001865 */
Richard Choue0381b82018-04-24 03:48:59 +00001866 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08001867
1868 // This is awful. It exists because there are two APIs for getting the SIM status
1869 // that don't return the complete set of values and have different types. In Keyguard we
1870 // need IccCardConstants, but TelephonyManager would only give us
1871 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08001872 final TelephonyManager tele = TelephonyManager.from(mContext);
Richard Choue0381b82018-04-24 03:48:59 +00001873 int simState = tele.getSimState(slotId);
1874 State state;
1875 try {
1876 state = State.intToState(simState);
1877 } catch(IllegalArgumentException ex) {
1878 Log.w(TAG, "Unknown sim state: " + simState);
1879 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05001880 }
Richard Choue0381b82018-04-24 03:48:59 +00001881 SimData data = mSimDatas.get(subId);
1882 final boolean changed;
1883 if (data == null) {
1884 data = new SimData(state, slotId, subId);
1885 mSimDatas.put(subId, data);
1886 changed = true; // no data yet; force update
1887 } else {
1888 changed = data.simState != state;
1889 data.simState = state;
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001890 }
Richard Choue0381b82018-04-24 03:48:59 +00001891 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07001892 }
1893
1894 public static boolean isSimPinSecure(IccCardConstants.State state) {
1895 final IccCardConstants.State simState = state;
1896 return (simState == IccCardConstants.State.PIN_REQUIRED
1897 || simState == IccCardConstants.State.PUK_REQUIRED
1898 || simState == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07001899 }
Jim Miller8f09fd22013-03-14 19:04:28 -07001900
1901 public DisplayClientState getCachedDisplayClientState() {
1902 return mDisplayClientState;
1903 }
Jim Miller20daffd2013-10-07 14:59:53 -07001904
1905 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
1906 // (KeyguardViewMediator, KeyguardHostView)
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001907 public void dispatchStartedWakingUp() {
1908 synchronized (this) {
1909 mDeviceInteractive = true;
1910 }
1911 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
1912 }
1913
Jorim Jaggi95e40382015-09-16 15:53:42 -07001914 public void dispatchStartedGoingToSleep(int why) {
1915 mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
1916 }
1917
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001918 public void dispatchFinishedGoingToSleep(int why) {
1919 synchronized(this) {
1920 mDeviceInteractive = false;
1921 }
1922 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
1923 }
1924
Jim Miller20daffd2013-10-07 14:59:53 -07001925 public void dispatchScreenTurnedOn() {
1926 synchronized (this) {
1927 mScreenOn = true;
1928 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001929 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
Jim Miller20daffd2013-10-07 14:59:53 -07001930 }
1931
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001932 public void dispatchScreenTurnedOff() {
Jim Miller20daffd2013-10-07 14:59:53 -07001933 synchronized(this) {
1934 mScreenOn = false;
1935 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001936 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
Jim Miller20daffd2013-10-07 14:59:53 -07001937 }
1938
Selim Cinek99415392016-09-09 14:58:41 -07001939 public void dispatchDreamingStarted() {
1940 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 1, 0));
1941 }
1942
1943 public void dispatchDreamingStopped() {
1944 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 0, 0));
1945 }
1946
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001947 public boolean isDeviceInteractive() {
1948 return mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -07001949 }
Jim Miller52a61332014-11-12 19:29:51 -08001950
Jorim Jaggi95e40382015-09-16 15:53:42 -07001951 public boolean isGoingToSleep() {
1952 return mGoingToSleep;
1953 }
1954
Jim Miller52a61332014-11-12 19:29:51 -08001955 /**
1956 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
1957 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08001958 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08001959 */
1960 public int getNextSubIdForState(State state) {
1961 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08001962 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08001963 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
1964 for (int i = 0; i < list.size(); i++) {
1965 final SubscriptionInfo info = list.get(i);
1966 final int id = info.getSubscriptionId();
Sanket Padawe7e460252017-03-10 16:18:20 -08001967 int slotId = SubscriptionManager.getSlotIndex(id);
Jim Miller52a61332014-11-12 19:29:51 -08001968 if (state == getSimState(id) && bestSlotId > slotId ) {
1969 resultId = id;
1970 bestSlotId = slotId;
1971 }
1972 }
1973 return resultId;
1974 }
1975
1976 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
1977 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
1978 for (int i = 0; i < list.size(); i++) {
1979 SubscriptionInfo info = list.get(i);
1980 if (subId == info.getSubscriptionId()) return info;
1981 }
1982 return null; // not found
1983 }
Jason Monkab525272015-07-13 17:02:49 -04001984
Alex Chauff7653d2018-02-01 17:18:08 +00001985 /**
1986 * @return a cached version of DevicePolicyManager.isLogoutEnabled()
1987 */
1988 public boolean isLogoutEnabled() {
1989 return mLogoutEnabled;
1990 }
1991
1992 private void updateLogoutEnabled() {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001993 checkIsHandlerThread();
Alex Chauff7653d2018-02-01 17:18:08 +00001994 boolean logoutEnabled = mDevicePolicyManager.isLogoutEnabled();
1995 if (mLogoutEnabled != logoutEnabled) {
1996 mLogoutEnabled = logoutEnabled;
1997 for (int i = 0; i < mCallbacks.size(); i++) {
1998 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1999 if (cb != null) {
2000 cb.onLogoutEnabledChanged();
2001 }
2002 }
2003 }
2004 }
2005
Adrian Roos30a2ae62018-04-25 19:09:50 +02002006 private void checkIsHandlerThread() {
2007 if (sDisableHandlerCheckForTesting) {
2008 return;
2009 }
2010 if (!mHandler.getLooper().isCurrentThread()) {
2011 Log.wtf(TAG, "must call on mHandler's thread "
2012 + mHandler.getLooper().getThread() + ", not " + Thread.currentThread());
2013 }
2014 }
2015
2016 /**
2017 * Turn off the handler check for testing.
2018 *
2019 * This is necessary because currently tests are not too careful about which thread they call
2020 * into this class on.
2021 *
2022 * Note that this must be called before scheduling any work involving KeyguardUpdateMonitor
2023 * instances.
2024 *
2025 * TODO: fix the tests and remove this.
2026 */
2027 @VisibleForTesting
2028 public static void disableHandlerCheckForTesting(Instrumentation instrumentation) {
2029 Preconditions.checkNotNull(instrumentation, "Must only call this method in tests!");
2030 // Don't need synchronization here *if* the callers follow the contract and call this only
2031 // before scheduling work for KeyguardUpdateMonitor on other threads, because the scheduling
2032 // of that work forces a happens-before relationship.
2033 sDisableHandlerCheckForTesting = true;
2034 }
2035
Jason Monkab525272015-07-13 17:02:49 -04002036 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2037 pw.println("KeyguardUpdateMonitor state:");
2038 pw.println(" SIM States:");
2039 for (SimData data : mSimDatas.values()) {
2040 pw.println(" " + data.toString());
2041 }
2042 pw.println(" Subs:");
2043 if (mSubscriptionInfo != null) {
2044 for (int i = 0; i < mSubscriptionInfo.size(); i++) {
2045 pw.println(" " + mSubscriptionInfo.get(i));
2046 }
2047 }
2048 pw.println(" Service states:");
2049 for (int subId : mServiceStates.keySet()) {
2050 pw.println(" " + subId + "=" + mServiceStates.get(subId));
2051 }
Jim Millerd72d5ac2015-09-29 18:55:32 -07002052 if (mFpm != null && mFpm.isHardwareDetected()) {
2053 final int userId = ActivityManager.getCurrentUser();
2054 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
2055 pw.println(" Fingerprint state (user=" + userId + ")");
2056 pw.println(" allowed=" + isUnlockingWithFingerprintAllowed());
2057 pw.println(" auth'd=" + mUserFingerprintAuthenticated.get(userId));
2058 pw.println(" authSinceBoot="
2059 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
2060 pw.println(" disabled(DPM)=" + isFingerprintDisabled(userId));
2061 pw.println(" possible=" + isUnlockWithFingerprintPossible(userId));
2062 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002063 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
2064 }
Jason Monkab525272015-07-13 17:02:49 -04002065 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002066}