blob: 8b48130297e43a73abff05ba6add7f8d49109619 [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;
Bill Lin6c7ccab2018-07-05 17:48:49 +080085import com.android.settingslib.WirelessUtils;
Winson Chungaa357452017-10-31 11:35:30 -070086import com.android.systemui.recents.misc.SysUiTaskStackChangeListener;
Winson Chung2cf6ad82017-11-09 17:36:59 -080087import com.android.systemui.shared.system.ActivityManagerWrapper;
Jorim Jaggi86bed402015-08-20 18:20:02 -070088
Kevin Chyn36778ff2017-09-07 19:55:38 -070089import com.google.android.collect.Lists;
90
Jason Monkab525272015-07-13 17:02:49 -040091import java.io.FileDescriptor;
92import java.io.PrintWriter;
Jim Millerdcb3d842012-08-23 19:18:12 -070093import java.lang.ref.WeakReference;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080094import java.util.ArrayList;
Jim Miller52a61332014-11-12 19:29:51 -080095import java.util.HashMap;
96import java.util.List;
97import java.util.Map.Entry;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080098
99/**
100 * Watches for updates that may be interesting to the keyguard, and provides
101 * the up to date information as well as a registration for callbacks that care
102 * to be updated.
103 *
104 * Note: under time crunch, this has been extended to include some stuff that
105 * doesn't really belong here. see {@link #handleBatteryUpdate} where it shutdowns
Jim Miller258341c2012-08-30 16:50:10 -0700106 * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()}
107 * and {@link #clearFailedUnlockAttempts()}. Maybe we should rename this 'KeyguardContext'...
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800108 */
Adrian Roos46842d92014-03-27 14:58:03 +0100109public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800110
Jim Millerbbf1a742012-07-17 18:30:30 -0700111 private static final String TAG = "KeyguardUpdateMonitor";
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100112 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller52a61332014-11-12 19:29:51 -0800113 private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
Jim Millerbbf1a742012-07-17 18:30:30 -0700114 private static final int LOW_BATTERY_THRESHOLD = 20;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800115
Jorim Jaggie7b12522014-08-06 16:41:21 +0200116 private static final String ACTION_FACE_UNLOCK_STARTED
117 = "com.android.facelock.FACE_UNLOCK_STARTED";
118 private static final String ACTION_FACE_UNLOCK_STOPPED
119 = "com.android.facelock.FACE_UNLOCK_STOPPED";
120
Jim Millerbbf1a742012-07-17 18:30:30 -0700121 // Callback messages
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800122 private static final int MSG_TIME_UPDATE = 301;
123 private static final int MSG_BATTERY_UPDATE = 302;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800124 private static final int MSG_SIM_STATE_CHANGE = 304;
Jim Miller47088bb2009-11-24 00:40:16 -0800125 private static final int MSG_RINGER_MODE_CHANGED = 305;
Jim Millerc23024d2010-02-24 15:37:00 -0800126 private static final int MSG_PHONE_STATE_CHANGED = 306;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700127 private static final int MSG_DEVICE_PROVISIONED = 308;
Jim Miller57375342012-09-09 15:20:31 -0700128 private static final int MSG_DPM_STATE_CHANGED = 309;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500129 private static final int MSG_USER_SWITCHING = 310;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700130 private static final int MSG_KEYGUARD_RESET = 312;
Jim Millerf41fc962014-06-18 16:33:51 -0700131 private static final int MSG_BOOT_COMPLETED = 313;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500132 private static final int MSG_USER_SWITCH_COMPLETE = 314;
Jim Millerf41fc962014-06-18 16:33:51 -0700133 private static final int MSG_USER_INFO_CHANGED = 317;
134 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700135 private static final int MSG_STARTED_WAKING_UP = 319;
136 private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700137 private static final int MSG_STARTED_GOING_TO_SLEEP = 321;
Adrian Roosb6011622014-05-14 15:52:53 +0200138 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700139 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
140 private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
Jason Monk052082c2015-06-11 11:35:23 -0400141 private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
Etan Cohen47051d82015-07-06 16:19:04 -0700142 private static final int MSG_SERVICE_STATE_CHANGE = 330;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700143 private static final int MSG_SCREEN_TURNED_ON = 331;
144 private static final int MSG_SCREEN_TURNED_OFF = 332;
Selim Cinek99415392016-09-09 14:58:41 -0700145 private static final int MSG_DREAMING_STATE_CHANGED = 333;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700146 private static final int MSG_USER_UNLOCKED = 334;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700147 private static final int MSG_ASSISTANT_STACK_CHANGED = 335;
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700148 private static final int MSG_FINGERPRINT_AUTHENTICATION_CONTINUE = 336;
Alex Chauff7653d2018-02-01 17:18:08 +0000149 private static final int MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED = 337;
Bill Lin6c7ccab2018-07-05 17:48:49 +0800150 private static final int MSG_TELEPHONY_CAPABLE = 338;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800151
Jorim Jaggi86bed402015-08-20 18:20:02 -0700152 /** Fingerprint state: Not listening to fingerprint. */
153 private static final int FINGERPRINT_STATE_STOPPED = 0;
154
155 /** Fingerprint state: Listening. */
156 private static final int FINGERPRINT_STATE_RUNNING = 1;
157
158 /**
159 * Fingerprint state: Cancelling and waiting for the confirmation from FingerprintService to
160 * send us the confirmation that cancellation has happened.
161 */
162 private static final int FINGERPRINT_STATE_CANCELLING = 2;
163
164 /**
165 * Fingerprint state: During cancelling we got another request to start listening, so when we
166 * receive the cancellation done signal, we should start listening again.
167 */
168 private static final int FINGERPRINT_STATE_CANCELLING_RESTARTING = 3;
169
Adrian Roos0c859ae2015-11-23 16:47:50 -0800170 private static final int DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT = 5000000;
171
Jorim Jaggi031f7952016-09-01 16:39:26 -0700172 private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName(
173 "com.android.settings", "com.android.settings.FallbackHome");
174
Adrian Roosca8a2162017-08-17 19:00:58 +0200175
176 /**
177 * If true, the system is in the half-boot-to-decryption-screen state.
178 * Prudently disable lockscreen.
179 */
180 public static final boolean CORE_APPS_ONLY;
181 static {
182 try {
183 CORE_APPS_ONLY = IPackageManager.Stub.asInterface(
184 ServiceManager.getService("package")).isOnlyCoreApps();
185 } catch (RemoteException e) {
186 throw e.rethrowFromSystemServer();
187 }
188 }
189
Jim Millerdcb3d842012-08-23 19:18:12 -0700190 private static KeyguardUpdateMonitor sInstance;
191
Jim Millerbbf1a742012-07-17 18:30:30 -0700192 private final Context mContext;
Jim Miller52a61332014-11-12 19:29:51 -0800193 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
Etan Cohen47051d82015-07-06 16:19:04 -0700194 HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700195
Jim Millerbbf1a742012-07-17 18:30:30 -0700196 private int mRingMode;
197 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400198 private boolean mKeyguardIsVisible;
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700199 private boolean mKeyguardGoingAway;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700200 private boolean mGoingToSleep;
Adrian Roosb6011622014-05-14 15:52:53 +0200201 private boolean mBouncer;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800202 private boolean mBootCompleted;
Jorim Jaggi031f7952016-09-01 16:39:26 -0700203 private boolean mNeedsSlowUnlockTransition;
Jorim Jaggid11d1a92016-08-16 16:02:32 -0700204 private boolean mHasLockscreenWallpaper;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700205 private boolean mAssistantVisible;
206 private boolean mKeyguardOccluded;
Bill Lin6c7ccab2018-07-05 17:48:49 +0800207 @VisibleForTesting
208 protected boolean mTelephonyCapable;
Jim Millerbbf1a742012-07-17 18:30:30 -0700209
Jim Millerdcb3d842012-08-23 19:18:12 -0700210 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700211 private boolean mDeviceProvisioned;
212
Jim Millerdcb3d842012-08-23 19:18:12 -0700213 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700214 private BatteryStatus mBatteryStatus;
215
Rakesh Iyera7aa4d62016-01-19 17:27:23 -0800216 private final StrongAuthTracker mStrongAuthTracker;
Jim Millerbbf1a742012-07-17 18:30:30 -0700217
Jim Miller6212cc02012-09-05 17:35:31 -0700218 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700219 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800220 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700221
Brian Colonnaa5239892013-04-15 11:45:40 -0400222 private boolean mSwitchingUser;
223
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700224 private boolean mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -0700225 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800226 private SubscriptionManager mSubscriptionManager;
227 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700228 private TrustManager mTrustManager;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700229 private UserManager mUserManager;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700230 private int mFingerprintRunningState = FINGERPRINT_STATE_STOPPED;
Michal Karpinskic52f8672016-11-18 11:32:45 +0000231 private LockPatternUtils mLockPatternUtils;
Kevin Chyn36778ff2017-09-07 19:55:38 -0700232 private final IDreamManager mDreamManager;
233 private boolean mIsDreaming;
Alex Chauff7653d2018-02-01 17:18:08 +0000234 private final DevicePolicyManager mDevicePolicyManager;
235 private boolean mLogoutEnabled;
Jim Miller20daffd2013-10-07 14:59:53 -0700236
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700237 /**
238 * Short delay before restarting fingerprint authentication after a successful try
239 * This should be slightly longer than the time between onFingerprintAuthenticated and
240 * setKeyguardGoingAway(true).
241 */
242 private static final int FINGERPRINT_CONTINUE_DELAY_MS = 500;
243
Kevin Chyn0c45b072017-04-24 16:27:11 -0700244 // If FP daemon dies, keyguard should retry after a short delay
245 private int mHardwareUnavailableRetryCount = 0;
246 private static final int HW_UNAVAILABLE_TIMEOUT = 3000; // ms
247 private static final int HW_UNAVAILABLE_RETRY_MAX = 3;
248
Jason Monk7bb59302018-05-10 19:38:18 -0700249 private final Handler mHandler = new Handler(Looper.getMainLooper()) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700250 @Override
251 public void handleMessage(Message msg) {
252 switch (msg.what) {
253 case MSG_TIME_UPDATE:
254 handleTimeUpdate();
255 break;
256 case MSG_BATTERY_UPDATE:
257 handleBatteryUpdate((BatteryStatus) msg.obj);
258 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700259 case MSG_SIM_STATE_CHANGE:
Jim Miller52a61332014-11-12 19:29:51 -0800260 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700261 break;
262 case MSG_RINGER_MODE_CHANGED:
263 handleRingerModeChange(msg.arg1);
264 break;
265 case MSG_PHONE_STATE_CHANGED:
Adrian Roosb6011622014-05-14 15:52:53 +0200266 handlePhoneStateChanged((String) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700267 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700268 case MSG_DEVICE_PROVISIONED:
269 handleDeviceProvisioned();
270 break;
271 case MSG_DPM_STATE_CHANGED:
272 handleDevicePolicyManagerStateChanged();
273 break;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500274 case MSG_USER_SWITCHING:
Adrian Roosb6011622014-05-14 15:52:53 +0200275 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
Chris Wrenf41c61b2012-11-29 15:19:54 -0500276 break;
277 case MSG_USER_SWITCH_COMPLETE:
278 handleUserSwitchComplete(msg.arg1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700279 break;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700280 case MSG_KEYGUARD_RESET:
281 handleKeyguardReset();
282 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200283 case MSG_KEYGUARD_BOUNCER_CHANGED:
284 handleKeyguardBouncerChanged(msg.arg1);
285 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800286 case MSG_BOOT_COMPLETED:
287 handleBootCompleted();
288 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700289 case MSG_USER_INFO_CHANGED:
290 handleUserInfoChanged(msg.arg1);
291 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400292 case MSG_REPORT_EMERGENCY_CALL_ACTION:
293 handleReportEmergencyCallAction();
294 break;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700295 case MSG_STARTED_GOING_TO_SLEEP:
296 handleStartedGoingToSleep(msg.arg1);
297 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700298 case MSG_FINISHED_GOING_TO_SLEEP:
299 handleFinishedGoingToSleep(msg.arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700300 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700301 case MSG_STARTED_WAKING_UP:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700302 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_STARTED_WAKING_UP");
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700303 handleStartedWakingUp();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700304 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -0700305 break;
Jorim Jaggie7b12522014-08-06 16:41:21 +0200306 case MSG_FACE_UNLOCK_STATE_CHANGED:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700307 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_FACE_UNLOCK_STATE_CHANGED");
Adrian Roos4a410172014-08-20 17:41:44 +0200308 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
Nick Desaulniers1d396752016-07-25 15:05:33 -0700309 Trace.endSection();
Jorim Jaggie7b12522014-08-06 16:41:21 +0200310 break;
Jim Miller52a61332014-11-12 19:29:51 -0800311 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
312 handleSimSubscriptionInfoChanged();
313 break;
Jason Monk052082c2015-06-11 11:35:23 -0400314 case MSG_AIRPLANE_MODE_CHANGED:
315 handleAirplaneModeChanged();
316 break;
Etan Cohen47051d82015-07-06 16:19:04 -0700317 case MSG_SERVICE_STATE_CHANGE:
318 handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
319 break;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700320 case MSG_SCREEN_TURNED_ON:
321 handleScreenTurnedOn();
322 break;
323 case MSG_SCREEN_TURNED_OFF:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700324 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_SCREEN_TURNED_ON");
Jorim Jaggif1518da2015-07-30 11:56:36 -0700325 handleScreenTurnedOff();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700326 Trace.endSection();
Jorim Jaggif1518da2015-07-30 11:56:36 -0700327 break;
Selim Cinek99415392016-09-09 14:58:41 -0700328 case MSG_DREAMING_STATE_CHANGED:
329 handleDreamingStateChanged(msg.arg1);
330 break;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700331 case MSG_USER_UNLOCKED:
332 handleUserUnlocked();
333 break;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700334 case MSG_ASSISTANT_STACK_CHANGED:
335 mAssistantVisible = (boolean)msg.obj;
336 updateFingerprintListeningState();
337 break;
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700338 case MSG_FINGERPRINT_AUTHENTICATION_CONTINUE:
339 updateFingerprintListeningState();
340 break;
Alex Chauff7653d2018-02-01 17:18:08 +0000341 case MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED:
342 updateLogoutEnabled();
343 break;
Bill Lin6c7ccab2018-07-05 17:48:49 +0800344 case MSG_TELEPHONY_CAPABLE:
345 updateTelephonyCapable((boolean)msg.obj);
346 break;
Jason Monk7bb59302018-05-10 19:38:18 -0700347 default:
348 super.handleMessage(msg);
349 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700350 }
351 }
352 };
353
Wink Savilled09c4ca2014-11-22 10:08:16 -0800354 private OnSubscriptionsChangedListener mSubscriptionListener =
355 new OnSubscriptionsChangedListener() {
Jim Miller52a61332014-11-12 19:29:51 -0800356 @Override
Wink Savilled09c4ca2014-11-22 10:08:16 -0800357 public void onSubscriptionsChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800358 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
359 }
360 };
361
Adrian Roos46842d92014-03-27 14:58:03 +0100362 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200363 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Jim Miller9f0753f2015-03-23 23:59:22 -0700364 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200365 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100366
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700367 private static int sCurrentUser;
Selim Cinekbbe19242017-12-08 15:42:08 -0800368 private Runnable mUpdateFingerprintListeningState = this::updateFingerprintListeningState;
Adrian Roos30a2ae62018-04-25 19:09:50 +0200369 private static boolean sDisableHandlerCheckForTesting;
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700370
371 public synchronized static void setCurrentUser(int currentUser) {
372 sCurrentUser = currentUser;
373 }
374
375 public synchronized static int getCurrentUser() {
376 return sCurrentUser;
377 }
378
Adrian Roos46842d92014-03-27 14:58:03 +0100379 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700380 public void onTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200381 checkIsHandlerThread();
Adrian Roos46842d92014-03-27 14:58:03 +0100382 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200383 for (int i = 0; i < mCallbacks.size(); i++) {
384 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
385 if (cb != null) {
386 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700387 if (enabled && flags != 0) {
388 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200389 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200390 }
391 }
Adrian Roos46842d92014-03-27 14:58:03 +0100392 }
393
Lucas Dupinef886542018-01-03 16:03:07 -0800394 @Override
395 public void onTrustError(CharSequence message) {
396 dispatchErrorMessage(message);
397 }
398
Adrian Roos30a2ae62018-04-25 19:09:50 +0200399 private void handleSimSubscriptionInfoChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800400 if (DEBUG_SIM_STATES) {
401 Log.v(TAG, "onSubscriptionInfoChanged()");
Wink Savilled09c4ca2014-11-22 10:08:16 -0800402 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
403 if (sil != null) {
404 for (SubscriptionInfo subInfo : sil) {
405 Log.v(TAG, "SubInfo:" + subInfo);
406 }
407 } else {
408 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800409 }
410 }
411 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
412
413 // Hack level over 9000: Because the subscription id is not yet valid when we see the
414 // first update in handleSimStateChange, we need to force refresh all all SIM states
415 // so the subscription id for them is consistent.
Richard Choue0381b82018-04-24 03:48:59 +0000416 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
417 for (int i = 0; i < subscriptionInfos.size(); i++) {
418 SubscriptionInfo info = subscriptionInfos.get(i);
419 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
420 if (changed) {
421 changedSubscriptions.add(info);
422 }
423 }
424 for (int i = 0; i < changedSubscriptions.size(); i++) {
425 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800426 for (int j = 0; j < mCallbacks.size(); j++) {
427 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
428 if (cb != null) {
429 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
430 }
431 }
432 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500433 for (int j = 0; j < mCallbacks.size(); j++) {
434 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
435 if (cb != null) {
436 cb.onRefreshCarrierInfo();
437 }
438 }
Jim Miller52a61332014-11-12 19:29:51 -0800439 }
440
Jason Monk052082c2015-06-11 11:35:23 -0400441 private void handleAirplaneModeChanged() {
442 for (int j = 0; j < mCallbacks.size(); j++) {
443 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
444 if (cb != null) {
445 cb.onRefreshCarrierInfo();
446 }
447 }
448 }
449
Wink Savilled09c4ca2014-11-22 10:08:16 -0800450 /** @return List of SubscriptionInfo records, maybe empty but never null */
Adrian Roos316bf542016-08-23 17:53:07 +0200451 public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800452 List<SubscriptionInfo> sil = mSubscriptionInfo;
453 if (sil == null || forceReload) {
454 sil = mSubscriptionManager.getActiveSubscriptionInfoList();
455 }
456 if (sil == null) {
457 // getActiveSubscriptionInfoList was null callers expect an empty list.
458 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
459 } else {
460 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800461 }
462 return mSubscriptionInfo;
463 }
464
Adrian Roos7861c662014-07-25 15:37:28 +0200465 @Override
466 public void onTrustManagedChanged(boolean managed, int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200467 checkIsHandlerThread();
Adrian Roos7861c662014-07-25 15:37:28 +0200468 mUserTrustIsManaged.put(userId, managed);
469
470 for (int i = 0; i < mCallbacks.size(); i++) {
471 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
472 if (cb != null) {
473 cb.onTrustManagedChanged(userId);
474 }
475 }
476 }
477
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700478 /**
479 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is goingAway
480 * @param goingAway
481 */
482 public void setKeyguardGoingAway(boolean goingAway) {
483 mKeyguardGoingAway = goingAway;
Kevin Chyne22f1342017-09-26 10:03:38 -0700484 updateFingerprintListeningState();
Kevin Chynf3b8fbd2017-05-03 22:24:31 -0700485 }
486
Kevin Chyn2fefd462017-04-28 12:18:19 -0700487 /**
488 * Updates KeyguardUpdateMonitor's internal state to know if keyguard is occluded
489 * @param occluded
490 */
491 public void setKeyguardOccluded(boolean occluded) {
492 mKeyguardOccluded = occluded;
493 updateFingerprintListeningState();
494 }
495
Kevin Chyn36778ff2017-09-07 19:55:38 -0700496 /**
497 * @return a cached version of DreamManager.isDreaming()
498 */
499 public boolean isDreaming() {
500 return mIsDreaming;
501 }
502
503 /**
504 * If the device is dreaming, awakens the device
505 */
506 public void awakenFromDream() {
507 if (mIsDreaming && mDreamManager != null) {
508 try {
509 mDreamManager.awaken();
510 } catch (RemoteException e) {
511 Log.e(TAG, "Unable to awaken from dream");
512 }
513 }
514 }
515
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700516 private void onFingerprintAuthenticated(int userId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700517 Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
Jim Miller9f0753f2015-03-23 23:59:22 -0700518 mUserFingerprintAuthenticated.put(userId, true);
Kevin Chyn3fdbbf82017-05-06 15:11:53 -0700519 // Update/refresh trust state only if user can skip bouncer
520 if (getUserCanSkipBouncer(userId)) {
521 mTrustManager.unlockedByFingerprintForUser(userId);
522 }
Kevin Chyn625a0142017-04-10 14:53:59 -0700523 // Don't send cancel if authentication succeeds
524 mFingerprintCancelSignal = null;
Jim Millerf41fc962014-06-18 16:33:51 -0700525 for (int i = 0; i < mCallbacks.size(); i++) {
526 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
527 if (cb != null) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700528 cb.onFingerprintAuthenticated(userId);
Jim Millerf41fc962014-06-18 16:33:51 -0700529 }
530 }
Kevin Chyn2fefd462017-04-28 12:18:19 -0700531
Kevin Chyn0f3e0b12017-07-20 16:56:11 -0700532 mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_FINGERPRINT_AUTHENTICATION_CONTINUE),
533 FINGERPRINT_CONTINUE_DELAY_MS);
534
Kevin Chyn2fefd462017-04-28 12:18:19 -0700535 // Only authenticate fingerprint once when assistant is visible
536 mAssistantVisible = false;
Kevin Chyn2fefd462017-04-28 12:18:19 -0700537
Nick Desaulniers1d396752016-07-25 15:05:33 -0700538 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700539 }
540
Jim Millerce7eb6d2015-04-03 19:29:13 -0700541 private void handleFingerprintAuthFailed() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700542 for (int i = 0; i < mCallbacks.size(); i++) {
543 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
544 if (cb != null) {
545 cb.onFingerprintAuthFailed();
546 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700547 }
Jim Millerce7eb6d2015-04-03 19:29:13 -0700548 handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized));
549 }
Jim Millerf41fc962014-06-18 16:33:51 -0700550
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700551 private void handleFingerprintAcquired(int acquireInfo) {
552 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
553 return;
554 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700555 for (int i = 0; i < mCallbacks.size(); i++) {
556 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
557 if (cb != null) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700558 cb.onFingerprintAcquired();
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700559 }
560 }
561 }
562
Jim Miller837fa7e2016-08-08 20:16:22 -0700563 private void handleFingerprintAuthenticated(int authUserId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700564 Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
Jim Millerf41fc962014-06-18 16:33:51 -0700565 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700566 final int userId;
567 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800568 userId = ActivityManager.getService().getCurrentUser().id;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700569 } catch (RemoteException e) {
570 Log.e(TAG, "Failed to get current user id: ", e);
571 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700572 }
Jim Miller837fa7e2016-08-08 20:16:22 -0700573 if (userId != authUserId) {
574 Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId);
575 return;
576 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700577 if (isFingerprintDisabled(userId)) {
578 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
579 return;
580 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700581 onFingerprintAuthenticated(userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700582 } finally {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700583 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
Jim Millerf41fc962014-06-18 16:33:51 -0700584 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700585 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700586 }
587
Jim Miller9f0753f2015-03-23 23:59:22 -0700588 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700589 for (int i = 0; i < mCallbacks.size(); i++) {
590 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
591 if (cb != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700592 cb.onFingerprintHelp(msgId, helpString);
593 }
594 }
595 }
596
Kevin Chyn0c45b072017-04-24 16:27:11 -0700597 private Runnable mRetryFingerprintAuthentication = new Runnable() {
598 @Override
599 public void run() {
600 Log.w(TAG, "Retrying fingerprint after HW unavailable, attempt " +
601 mHardwareUnavailableRetryCount);
602 updateFingerprintListeningState();
603 }
604 };
605
Jim Miller9f0753f2015-03-23 23:59:22 -0700606 private void handleFingerprintError(int msgId, String errString) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700607 if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
608 && mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
609 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
610 startListeningForFingerprint();
611 } else {
612 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
613 }
Kevin Chyn0c45b072017-04-24 16:27:11 -0700614
615 if (msgId == FingerprintManager.FINGERPRINT_ERROR_HW_UNAVAILABLE) {
616 if (mHardwareUnavailableRetryCount < HW_UNAVAILABLE_RETRY_MAX) {
617 mHardwareUnavailableRetryCount++;
618 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
619 mHandler.postDelayed(mRetryFingerprintAuthentication, HW_UNAVAILABLE_TIMEOUT);
620 }
621 }
622
Kevin Chyndf9d33e2017-05-03 21:40:12 -0700623 if (msgId == FingerprintManager.FINGERPRINT_ERROR_LOCKOUT_PERMANENT) {
624 mLockPatternUtils.requireStrongAuth(
625 LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_LOCKOUT,
626 getCurrentUser());
627 }
628
Jim Miller9f0753f2015-03-23 23:59:22 -0700629 for (int i = 0; i < mCallbacks.size(); i++) {
630 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
631 if (cb != null) {
632 cb.onFingerprintError(msgId, errString);
Jim Millerf41fc962014-06-18 16:33:51 -0700633 }
634 }
635 }
636
Jorim Jaggi3a464782015-08-28 16:59:13 -0700637 private void handleFingerprintLockoutReset() {
638 updateFingerprintListeningState();
639 }
640
Jorim Jaggi86bed402015-08-20 18:20:02 -0700641 private void setFingerprintRunningState(int fingerprintRunningState) {
642 boolean wasRunning = mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
643 boolean isRunning = fingerprintRunningState == FINGERPRINT_STATE_RUNNING;
644 mFingerprintRunningState = fingerprintRunningState;
645
646 // Clients of KeyguardUpdateMonitor don't care about the internal state about the
647 // asynchronousness of the cancel cycle. So only notify them if the actualy running state
648 // has changed.
649 if (wasRunning != isRunning) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700650 notifyFingerprintRunningStateChanged();
651 }
652 }
653
654 private void notifyFingerprintRunningStateChanged() {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200655 checkIsHandlerThread();
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700656 for (int i = 0; i < mCallbacks.size(); i++) {
657 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
658 if (cb != null) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700659 cb.onFingerprintRunningStateChanged(isFingerprintDetectionRunning());
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700660 }
661 }
662 }
Adrian Roos4a410172014-08-20 17:41:44 +0200663 private void handleFaceUnlockStateChanged(boolean running, int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200664 checkIsHandlerThread();
Adrian Roos4a410172014-08-20 17:41:44 +0200665 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200666 for (int i = 0; i < mCallbacks.size(); i++) {
667 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
668 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200669 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200670 }
671 }
672 }
673
Adrian Roos4a410172014-08-20 17:41:44 +0200674 public boolean isFaceUnlockRunning(int userId) {
675 return mUserFaceUnlockRunning.get(userId);
676 }
677
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700678 public boolean isFingerprintDetectionRunning() {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700679 return mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700680 }
681
Jim Miller50e62182014-04-23 17:25:00 -0700682 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100683 // Don't allow trust agent if device is secured with a SIM PIN. This is here
684 // mainly because there's no other way to prompt the user to enter their SIM PIN
685 // once they get past the keyguard screen.
686 final boolean disabledBySimPin = isSimPinSecure();
687 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700688 }
689
Jim Miller06e34502014-07-17 14:46:05 -0700690 private boolean isFingerprintDisabled(int userId) {
691 final DevicePolicyManager dpm =
692 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
693 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
Adrian Roos733b6632015-08-21 14:32:35 -0700694 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0
695 || isSimPinSecure();
Jim Miller06e34502014-07-17 14:46:05 -0700696 }
697
Selim Cineke8bae622015-07-15 13:24:06 -0700698 public boolean getUserCanSkipBouncer(int userId) {
Selim Cinek1fcafc42015-07-20 14:39:25 -0700699 return getUserHasTrust(userId) || (mUserFingerprintAuthenticated.get(userId)
700 && isUnlockingWithFingerprintAllowed());
Selim Cineke8bae622015-07-15 13:24:06 -0700701 }
702
Adrian Roos46842d92014-03-27 14:58:03 +0100703 public boolean getUserHasTrust(int userId) {
Selim Cineke8bae622015-07-15 13:24:06 -0700704 return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100705 }
706
Adrian Roos7861c662014-07-25 15:37:28 +0200707 public boolean getUserTrustIsManaged(int userId) {
708 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
709 }
710
Selim Cinek1fcafc42015-07-20 14:39:25 -0700711 public boolean isUnlockingWithFingerprintAllowed() {
Michal Karpinskic52f8672016-11-18 11:32:45 +0000712 return mStrongAuthTracker.isUnlockingWithFingerprintAllowed();
Adrian Roosb5e47222015-08-14 15:53:06 -0700713 }
714
Lucas Dupin16013822018-05-17 18:00:16 -0700715 public boolean isUserInLockdown(int userId) {
716 return mStrongAuthTracker.getStrongAuthForUser(userId)
717 == LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
718 }
719
Jorim Jaggi031f7952016-09-01 16:39:26 -0700720 public boolean needsSlowUnlockTransition() {
721 return mNeedsSlowUnlockTransition;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700722 }
723
Adrian Roosb5e47222015-08-14 15:53:06 -0700724 public StrongAuthTracker getStrongAuthTracker() {
725 return mStrongAuthTracker;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700726 }
727
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700728 private void notifyStrongAuthStateChanged(int userId) {
Adrian Roos30a2ae62018-04-25 19:09:50 +0200729 checkIsHandlerThread();
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700730 for (int i = 0; i < mCallbacks.size(); i++) {
731 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
732 if (cb != null) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700733 cb.onStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700734 }
735 }
Selim Cinek1fcafc42015-07-20 14:39:25 -0700736 }
737
Adrian Roos91ba3072017-02-14 16:50:46 +0100738 public boolean isScreenOn() {
739 return mScreenOn;
740 }
741
Lucas Dupinef886542018-01-03 16:03:07 -0800742 private void dispatchErrorMessage(CharSequence message) {
743 for (int i = 0; i < mCallbacks.size(); i++) {
744 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
745 if (cb != null) {
746 cb.onTrustAgentErrorMessage(message);
747 }
748 }
749 }
750
Jim Miller8f09fd22013-03-14 19:04:28 -0700751 static class DisplayClientState {
752 public int clientGeneration;
753 public boolean clearing;
754 public PendingIntent intent;
755 public int playbackState;
756 public long playbackEventTime;
757 }
758
759 private DisplayClientState mDisplayClientState = new DisplayClientState();
760
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800761 @VisibleForTesting
Lucas Dupin7ff82b02018-05-16 12:14:10 -0700762 protected final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
Jim Millerbbf1a742012-07-17 18:30:30 -0700763
Jim Millerd72d5ac2015-09-29 18:55:32 -0700764 @Override
Jim Millerbbf1a742012-07-17 18:30:30 -0700765 public void onReceive(Context context, Intent intent) {
766 final String action = intent.getAction();
767 if (DEBUG) Log.d(TAG, "received broadcast " + action);
768
769 if (Intent.ACTION_TIME_TICK.equals(action)
770 || Intent.ACTION_TIME_CHANGED.equals(action)
Adrian Roos48c796c2014-09-01 14:59:23 +0200771 || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700772 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Jim Millerbbf1a742012-07-17 18:30:30 -0700773 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
774 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
775 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
776 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
777 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
Adrian Roos0c859ae2015-11-23 16:47:50 -0800778
779 final int maxChargingMicroAmp = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
780 int maxChargingMicroVolt = intent.getIntExtra(EXTRA_MAX_CHARGING_VOLTAGE, -1);
781 final int maxChargingMicroWatt;
782
783 if (maxChargingMicroVolt <= 0) {
784 maxChargingMicroVolt = DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT;
785 }
786 if (maxChargingMicroAmp > 0) {
787 // Calculating muW = muA * muV / (10^6 mu^2 / mu); splitting up the divisor
788 // to maintain precision equally on both factors.
789 maxChargingMicroWatt = (maxChargingMicroAmp / 1000)
790 * (maxChargingMicroVolt / 1000);
791 } else {
792 maxChargingMicroWatt = -1;
793 }
Jim Millerbbf1a742012-07-17 18:30:30 -0700794 final Message msg = mHandler.obtainMessage(
Adrian Roos7b043112015-07-10 13:00:33 -0700795 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
Adrian Roos0c859ae2015-11-23 16:47:50 -0800796 maxChargingMicroWatt));
Jim Millerbbf1a742012-07-17 18:30:30 -0700797 mHandler.sendMessage(msg);
798 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Bill Lin6c7ccab2018-07-05 17:48:49 +0800799 SimData args = SimData.fromIntent(intent);
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800800 // ACTION_SIM_STATE_CHANGED is rebroadcast after unlocking the device to
801 // keep compatibility with apps that aren't direct boot aware.
802 // SysUI should just ignore this broadcast because it was already received
803 // and processed previously.
804 if (intent.getBooleanExtra(TelephonyIntents.EXTRA_REBROADCAST_ON_UNLOCK, false)) {
Bill Lin6c7ccab2018-07-05 17:48:49 +0800805 // Guarantee mTelephonyCapable state after SysUI crash and restart
806 if (args.simState == State.ABSENT) {
807 mHandler.obtainMessage(MSG_TELEPHONY_CAPABLE, true).sendToTarget();
808 }
Lucas Dupin5e0f0d22018-02-26 13:32:16 -0800809 return;
810 }
Jim Millerbbf1a742012-07-17 18:30:30 -0700811 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -0800812 Log.v(TAG, "action " + action
813 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
814 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -0700815 }
Jim Miller52a61332014-11-12 19:29:51 -0800816 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
817 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -0700818 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
819 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
820 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
821 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
822 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
823 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Jason Monk052082c2015-06-11 11:35:23 -0400824 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
825 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800826 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700827 dispatchBootCompleted();
Etan Cohen47051d82015-07-06 16:19:04 -0700828 } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
829 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
830 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
831 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
832 if (DEBUG) {
833 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
834 + subId);
835 }
836 mHandler.sendMessage(
837 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
Alex Chauff7653d2018-02-01 17:18:08 +0000838 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED.equals(
839 action)) {
840 mHandler.sendEmptyMessage(MSG_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jim Millerbbf1a742012-07-17 18:30:30 -0700841 }
842 }
843 };
Jim Miller2de5ee82012-06-14 22:22:50 -0700844
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700845 private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
846
Jim Millerd72d5ac2015-09-29 18:55:32 -0700847 @Override
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700848 public void onReceive(Context context, Intent intent) {
849 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +0200850 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
851 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
852 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700853 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
854 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +0200855 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700856 Trace.beginSection("KeyguardUpdateMonitor.mBroadcastAllReceiver#onReceive ACTION_FACE_UNLOCK_STARTED");
Adrian Roos48c796c2014-09-01 14:59:23 +0200857 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
858 getSendingUserId()));
Nick Desaulniers1d396752016-07-25 15:05:33 -0700859 Trace.endSection();
Adrian Roos48c796c2014-09-01 14:59:23 +0200860 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
861 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
862 getSendingUserId()));
863 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
864 .equals(action)) {
865 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -0700866 } else if (ACTION_USER_UNLOCKED.equals(action)) {
867 mHandler.sendEmptyMessage(MSG_USER_UNLOCKED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700868 }
869 }
870 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700871
Jorim Jaggi3a464782015-08-28 16:59:13 -0700872 private final FingerprintManager.LockoutResetCallback mLockoutResetCallback
873 = new FingerprintManager.LockoutResetCallback() {
874 @Override
875 public void onLockoutReset() {
876 handleFingerprintLockoutReset();
877 }
878 };
879
Jim Miller9f0753f2015-03-23 23:59:22 -0700880 private FingerprintManager.AuthenticationCallback mAuthenticationCallback
881 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -0700882
883 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -0700884 public void onAuthenticationFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700885 handleFingerprintAuthFailed();
Jim Millerce7eb6d2015-04-03 19:29:13 -0700886 };
887
888 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700889 public void onAuthenticationSucceeded(AuthenticationResult result) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700890 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
Jim Miller837fa7e2016-08-08 20:16:22 -0700891 handleFingerprintAuthenticated(result.getUserId());
Nick Desaulniers1d396752016-07-25 15:05:33 -0700892 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700893 }
894
895 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700896 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700897 handleFingerprintHelp(helpMsgId, helpString.toString());
Jim Miller9f0753f2015-03-23 23:59:22 -0700898 }
899
900 @Override
901 public void onAuthenticationError(int errMsgId, CharSequence errString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700902 handleFingerprintError(errMsgId, errString.toString());
903 }
904
905 @Override
906 public void onAuthenticationAcquired(int acquireInfo) {
907 handleFingerprintAcquired(acquireInfo);
Jim Millerf41fc962014-06-18 16:33:51 -0700908 }
909 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700910 private CancellationSignal mFingerprintCancelSignal;
911 private FingerprintManager mFpm;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700912
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800913 /**
Jim Miller47088bb2009-11-24 00:40:16 -0800914 * When we receive a
915 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -0700916 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800917 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -0800918 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800919 */
Jim Miller52a61332014-11-12 19:29:51 -0800920 private static class SimData {
921 public State simState;
922 public int slotId;
923 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800924
Jim Miller52a61332014-11-12 19:29:51 -0800925 SimData(State state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -0800926 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -0800927 slotId = slot;
928 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -0800929 }
930
Jim Miller52a61332014-11-12 19:29:51 -0800931 static SimData fromIntent(Intent intent) {
932 State state;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800933 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
934 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
935 }
Wink Savillea639b312012-07-10 12:37:54 -0700936 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
Jim Miller52a61332014-11-12 19:29:51 -0800937 int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0);
938 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
Wink Savilled09c4ca2014-11-22 10:08:16 -0800939 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea639b312012-07-10 12:37:54 -0700940 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -0700941 final String absentReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700942 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -0700943
Wink Savillea639b312012-07-10 12:37:54 -0700944 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -0700945 absentReason)) {
Wink Savillea639b312012-07-10 12:37:54 -0700946 state = IccCardConstants.State.PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -0700947 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700948 state = IccCardConstants.State.ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -0700949 }
Wink Savillea639b312012-07-10 12:37:54 -0700950 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
951 state = IccCardConstants.State.READY;
952 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800953 final String lockedReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700954 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
955 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
956 state = IccCardConstants.State.PIN_REQUIRED;
957 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
958 state = IccCardConstants.State.PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800959 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700960 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800961 }
Wink Savillea639b312012-07-10 12:37:54 -0700962 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
963 state = IccCardConstants.State.NETWORK_LOCKED;
Wileen Chiu6b8b22e2014-10-29 22:48:21 +0530964 } else if (IccCardConstants.INTENT_VALUE_ICC_CARD_IO_ERROR.equals(stateExtra)) {
965 state = IccCardConstants.State.CARD_IO_ERROR;
Jim Miller109f1fd2012-09-19 20:44:16 -0700966 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
967 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
968 // This is required because telephony doesn't return to "READY" after
969 // these state transitions. See bug 7197471.
970 state = IccCardConstants.State.READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800971 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700972 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800973 }
Jim Miller52a61332014-11-12 19:29:51 -0800974 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800975 }
976
Jim Millerd72d5ac2015-09-29 18:55:32 -0700977 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800978 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -0800979 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800980 }
981 }
982
Adrian Roos12c1ef52014-06-04 13:54:08 +0200983 public static class BatteryStatus {
Adrian Roos7b043112015-07-10 13:00:33 -0700984 public static final int CHARGING_UNKNOWN = -1;
985 public static final int CHARGING_SLOWLY = 0;
986 public static final int CHARGING_REGULAR = 1;
987 public static final int CHARGING_FAST = 2;
988
Jim Miller16464b82011-10-20 21:10:13 -0700989 public final int status;
990 public final int level;
991 public final int plugged;
992 public final int health;
Adrian Roos0c859ae2015-11-23 16:47:50 -0800993 public final int maxChargingWattage;
994 public BatteryStatus(int status, int level, int plugged, int health,
995 int maxChargingWattage) {
Jim Miller16464b82011-10-20 21:10:13 -0700996 this.status = status;
997 this.level = level;
998 this.plugged = plugged;
999 this.health = health;
Adrian Roos0c859ae2015-11-23 16:47:50 -08001000 this.maxChargingWattage = maxChargingWattage;
Jim Miller16464b82011-10-20 21:10:13 -07001001 }
1002
Jim Millerbbf1a742012-07-17 18:30:30 -07001003 /**
Brian Muramatsua92a01b2012-09-05 21:54:39 -07001004 * Determine whether the device is plugged in (USB, power, or wireless).
Jim Millerbbf1a742012-07-17 18:30:30 -07001005 * @return true if the device is plugged in.
1006 */
Adrian Roosad3bc7f2014-10-30 18:29:38 +01001007 public boolean isPluggedIn() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001008 return plugged == BatteryManager.BATTERY_PLUGGED_AC
Brian Muramatsua92a01b2012-09-05 21:54:39 -07001009 || plugged == BatteryManager.BATTERY_PLUGGED_USB
1010 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Jim Millerbbf1a742012-07-17 18:30:30 -07001011 }
1012
1013 /**
Beverly2034c832018-03-19 11:18:51 -04001014 * Determine whether the device is plugged in (USB, power).
1015 * @return true if the device is plugged in wired (as opposed to wireless)
1016 */
1017 public boolean isPluggedInWired() {
1018 return plugged == BatteryManager.BATTERY_PLUGGED_AC
1019 || plugged == BatteryManager.BATTERY_PLUGGED_USB;
1020 }
1021
1022 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001023 * Whether or not the device is charged. Note that some devices never return 100% for
1024 * battery level, so this allows either battery level or status to determine if the
1025 * battery is charged.
1026 * @return true if the device is charged
1027 */
1028 public boolean isCharged() {
1029 return status == BATTERY_STATUS_FULL || level >= 100;
1030 }
1031
1032 /**
1033 * Whether battery is low and needs to be charged.
1034 * @return true if battery is low
1035 */
1036 public boolean isBatteryLow() {
1037 return level < LOW_BATTERY_THRESHOLD;
1038 }
1039
Adrian Roos7b043112015-07-10 13:00:33 -07001040 public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
Adrian Roos0c859ae2015-11-23 16:47:50 -08001041 return maxChargingWattage <= 0 ? CHARGING_UNKNOWN :
1042 maxChargingWattage < slowThreshold ? CHARGING_SLOWLY :
1043 maxChargingWattage > fastThreshold ? CHARGING_FAST :
Adrian Roos7b043112015-07-10 13:00:33 -07001044 CHARGING_REGULAR;
1045 }
Lucas Dupin3fcdd472018-01-19 19:06:45 -08001046
1047 @Override
1048 public String toString() {
1049 return "BatteryStatus{status=" + status + ",level=" + level + ",plugged=" + plugged
1050 + ",health=" + health + ",maxChargingWattage=" + maxChargingWattage + "}";
1051 }
Jim Miller16464b82011-10-20 21:10:13 -07001052 }
1053
Adrian Roosb5e47222015-08-14 15:53:06 -07001054 public class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001055 public StrongAuthTracker(Context context) {
1056 super(context);
1057 }
Adrian Roosb5e47222015-08-14 15:53:06 -07001058
1059 public boolean isUnlockingWithFingerprintAllowed() {
1060 int userId = getCurrentUser();
1061 return isFingerprintAllowedForUser(userId);
1062 }
1063
1064 public boolean hasUserAuthenticatedSinceBoot() {
1065 int userId = getCurrentUser();
1066 return (getStrongAuthForUser(userId)
1067 & STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
1068 }
1069
1070 @Override
1071 public void onStrongAuthRequiredChanged(int userId) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -07001072 notifyStrongAuthStateChanged(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -07001073 }
1074 }
1075
Jim Millerdcb3d842012-08-23 19:18:12 -07001076 public static KeyguardUpdateMonitor getInstance(Context context) {
1077 if (sInstance == null) {
1078 sInstance = new KeyguardUpdateMonitor(context);
1079 }
1080 return sInstance;
1081 }
1082
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001083 protected void handleStartedWakingUp() {
Nick Desaulniers1d396752016-07-25 15:05:33 -07001084 Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
Jorim Jaggi864e64b2015-05-20 14:13:23 -07001085 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001086 final int count = mCallbacks.size();
1087 for (int i = 0; i < count; i++) {
1088 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1089 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001090 cb.onStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -07001091 }
1092 }
Nick Desaulniers1d396752016-07-25 15:05:33 -07001093 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -07001094 }
1095
Jorim Jaggi95e40382015-09-16 15:53:42 -07001096 protected void handleStartedGoingToSleep(int arg1) {
Jim Millerf41fc962014-06-18 16:33:51 -07001097 clearFingerprintRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -07001098 final int count = mCallbacks.size();
1099 for (int i = 0; i < count; i++) {
1100 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1101 if (cb != null) {
Jorim Jaggi95e40382015-09-16 15:53:42 -07001102 cb.onStartedGoingToSleep(arg1);
1103 }
1104 }
1105 mGoingToSleep = true;
Jorim Jaggi95e40382015-09-16 15:53:42 -07001106 updateFingerprintListeningState();
1107 }
1108
1109 protected void handleFinishedGoingToSleep(int arg1) {
1110 mGoingToSleep = false;
1111 final int count = mCallbacks.size();
1112 for (int i = 0; i < count; i++) {
1113 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1114 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001115 cb.onFinishedGoingToSleep(arg1);
Jim Miller20daffd2013-10-07 14:59:53 -07001116 }
1117 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001118 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -07001119 }
1120
Jorim Jaggif1518da2015-07-30 11:56:36 -07001121 private void handleScreenTurnedOn() {
1122 final int count = mCallbacks.size();
1123 for (int i = 0; i < count; i++) {
1124 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1125 if (cb != null) {
1126 cb.onScreenTurnedOn();
1127 }
1128 }
1129 }
1130
1131 private void handleScreenTurnedOff() {
Kevin Chyn0c45b072017-04-24 16:27:11 -07001132 mHardwareUnavailableRetryCount = 0;
Jorim Jaggif1518da2015-07-30 11:56:36 -07001133 final int count = mCallbacks.size();
1134 for (int i = 0; i < count; i++) {
1135 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1136 if (cb != null) {
1137 cb.onScreenTurnedOff();
1138 }
1139 }
1140 }
1141
Selim Cinek99415392016-09-09 14:58:41 -07001142 private void handleDreamingStateChanged(int dreamStart) {
1143 final int count = mCallbacks.size();
Kevin Chyn36778ff2017-09-07 19:55:38 -07001144 mIsDreaming = dreamStart == 1;
Selim Cinek99415392016-09-09 14:58:41 -07001145 for (int i = 0; i < count; i++) {
1146 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1147 if (cb != null) {
Kevin Chyn36778ff2017-09-07 19:55:38 -07001148 cb.onDreamingStateChanged(mIsDreaming);
Selim Cinek99415392016-09-09 14:58:41 -07001149 }
1150 }
Kevin Chyn20a68dc2017-09-21 11:41:01 -07001151 updateFingerprintListeningState();
Selim Cinek99415392016-09-09 14:58:41 -07001152 }
1153
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001154 private void handleUserInfoChanged(int userId) {
1155 for (int i = 0; i < mCallbacks.size(); i++) {
1156 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1157 if (cb != null) {
1158 cb.onUserInfoChanged(userId);
1159 }
1160 }
1161 }
1162
Jorim Jaggidadafd42016-09-30 07:20:25 -07001163 private void handleUserUnlocked() {
1164 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1165 for (int i = 0; i < mCallbacks.size(); i++) {
1166 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1167 if (cb != null) {
1168 cb.onUserUnlocked();
1169 }
1170 }
1171 }
1172
Lucas Dupin7517b5d2017-08-22 12:51:25 -07001173 @VisibleForTesting
1174 protected KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001175 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -08001176 mSubscriptionManager = SubscriptionManager.from(context);
Michael Jurkafff56142012-11-28 16:51:00 -08001177 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001178 mStrongAuthTracker = new StrongAuthTracker(context);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001179
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001180 // Since device can't be un-provisioned, we only need to register a content observer
1181 // to update mDeviceProvisioned when we are...
1182 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001183 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001184 }
Jim Miller47088bb2009-11-24 00:40:16 -08001185
Jim Millerbbf1a742012-07-17 18:30:30 -07001186 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Adrian Roos7b043112015-07-10 13:00:33 -07001187 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001188
Jim Millerbbf1a742012-07-17 18:30:30 -07001189 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001190 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001191 filter.addAction(Intent.ACTION_TIME_TICK);
1192 filter.addAction(Intent.ACTION_TIME_CHANGED);
1193 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
1194 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Jason Monk052082c2015-06-11 11:35:23 -04001195 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001196 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Etan Cohen47051d82015-07-06 16:19:04 -07001197 filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -08001198 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -08001199 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Alex Chauff7653d2018-02-01 17:18:08 +00001200 filter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jason Monk7bb59302018-05-10 19:38:18 -07001201 context.registerReceiver(mBroadcastReceiver, filter, null, mHandler);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001202
Adam Cohenc276e822012-11-08 13:01:08 -08001203 final IntentFilter bootCompleteFilter = new IntentFilter();
1204 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1205 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
Jason Monk7bb59302018-05-10 19:38:18 -07001206 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter, null, mHandler);
Adam Cohenc276e822012-11-08 13:01:08 -08001207
Adrian Roos48c796c2014-09-01 14:59:23 +02001208 final IntentFilter allUserFilter = new IntentFilter();
1209 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
1210 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
1211 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
1212 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
1213 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001214 allUserFilter.addAction(ACTION_USER_UNLOCKED);
Adrian Roos48c796c2014-09-01 14:59:23 +02001215 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Jason Monk7bb59302018-05-10 19:38:18 -07001216 null, mHandler);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001217
Wink Saville071743f2015-01-12 17:11:04 -08001218 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001219 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001220 ActivityManager.getService().registerUserSwitchObserver(
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001221 new UserSwitchObserver() {
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001222 @Override
1223 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001224 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001225 newUserId, 0, reply));
1226 }
1227 @Override
1228 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001229 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +02001230 newUserId, 0));
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001231 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001232 }, TAG);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001233 } catch (RemoteException e) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001234 e.rethrowAsRuntimeException();
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001235 }
Adrian Roos46842d92014-03-27 14:58:03 +01001236
Jorim Jaggi237b0612015-05-01 14:28:49 -07001237 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
1238 mTrustManager.registerTrustListener(this);
Michal Karpinskic52f8672016-11-18 11:32:45 +00001239 mLockPatternUtils = new LockPatternUtils(context);
1240 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Jim Millerf41fc962014-06-18 16:33:51 -07001241
Kevin Chyn36778ff2017-09-07 19:55:38 -07001242 mDreamManager = IDreamManager.Stub.asInterface(
1243 ServiceManager.getService(DreamService.DREAM_SERVICE));
1244
Jorim Jaggi3f124262016-11-22 13:45:17 +01001245 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
1246 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
1247 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001248 updateFingerprintListeningState();
Jorim Jaggi3a464782015-08-28 16:59:13 -07001249 if (mFpm != null) {
1250 mFpm.addLockoutResetCallback(mLockoutResetCallback);
1251 }
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001252
Winson Chung2cf6ad82017-11-09 17:36:59 -08001253 ActivityManagerWrapper.getInstance().registerTaskStackListener(mTaskStackListener);
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001254 mUserManager = context.getSystemService(UserManager.class);
Alex Chauff7653d2018-02-01 17:18:08 +00001255 mDevicePolicyManager = context.getSystemService(DevicePolicyManager.class);
1256 mLogoutEnabled = mDevicePolicyManager.isLogoutEnabled();
Bill Lin6c7ccab2018-07-05 17:48:49 +08001257 updateAirplaneModeState();
1258 }
1259
1260 private void updateAirplaneModeState() {
1261 // ACTION_AIRPLANE_MODE_CHANGED do not broadcast if device set AirplaneMode ON and boot
1262 if (!WirelessUtils.isAirplaneModeOn(mContext)
1263 || mHandler.hasMessages(MSG_AIRPLANE_MODE_CHANGED)) {
1264 return;
1265 }
1266 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Jorim Jaggiea657062015-04-28 13:45:11 -07001267 }
1268
1269 private void updateFingerprintListeningState() {
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001270 // If this message exists, we should not authenticate again until this message is
1271 // consumed by the handler
1272 if (mHandler.hasMessages(MSG_FINGERPRINT_AUTHENTICATION_CONTINUE)) {
1273 return;
1274 }
Kevin Chyn0c45b072017-04-24 16:27:11 -07001275 mHandler.removeCallbacks(mRetryFingerprintAuthentication);
Jorim Jaggiea657062015-04-28 13:45:11 -07001276 boolean shouldListenForFingerprint = shouldListenForFingerprint();
Jorim Jaggi86bed402015-08-20 18:20:02 -07001277 if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING && !shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001278 stopListeningForFingerprint();
Jorim Jaggi86bed402015-08-20 18:20:02 -07001279 } else if (mFingerprintRunningState != FINGERPRINT_STATE_RUNNING
1280 && shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001281 startListeningForFingerprint();
1282 }
1283 }
1284
Kevin Chyn129f60f2017-08-11 17:24:42 -07001285 private boolean shouldListenForFingerprintAssistant() {
1286 return mAssistantVisible && mKeyguardOccluded
1287 && !mUserFingerprintAuthenticated.get(getCurrentUser(), false)
1288 && !mUserHasTrust.get(getCurrentUser(), false);
1289 }
1290
Jorim Jaggiea657062015-04-28 13:45:11 -07001291 private boolean shouldListenForFingerprint() {
Kevin Chynf3b8fbd2017-05-03 22:24:31 -07001292 return (mKeyguardIsVisible || !mDeviceInteractive ||
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001293 (mBouncer && !mKeyguardGoingAway) || mGoingToSleep ||
Kevin Chyn36778ff2017-09-07 19:55:38 -07001294 shouldListenForFingerprintAssistant() || (mKeyguardOccluded && mIsDreaming))
Kevin Chyn0f3e0b12017-07-20 16:56:11 -07001295 && !mSwitchingUser && !isFingerprintDisabled(getCurrentUser())
1296 && !mKeyguardGoingAway;
Jim Miller9f0753f2015-03-23 23:59:22 -07001297 }
1298
Jim Millerce7eb6d2015-04-03 19:29:13 -07001299 private void startListeningForFingerprint() {
Jorim Jaggi86bed402015-08-20 18:20:02 -07001300 if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING) {
1301 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING_RESTARTING);
1302 return;
1303 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001304 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -07001305 int userId = ActivityManager.getCurrentUser();
Jorim Jaggi71448a72015-08-18 19:49:04 -07001306 if (isUnlockWithFingerprintPossible(userId)) {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001307 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001308 mFingerprintCancelSignal.cancel();
1309 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001310 mFingerprintCancelSignal = new CancellationSignal();
Kevin Chynaae4a152018-01-18 11:48:09 -08001311 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null,
1312 userId);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001313 setFingerprintRunningState(FINGERPRINT_STATE_RUNNING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001314 }
1315 }
1316
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001317 public boolean isUnlockWithFingerprintPossible(int userId) {
Selim Cinek3122fa82015-06-18 01:38:59 -07001318 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
1319 && mFpm.getEnrolledFingerprints(userId).size() > 0;
1320 }
1321
Jorim Jaggiea657062015-04-28 13:45:11 -07001322 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001323 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
Jorim Jaggi86bed402015-08-20 18:20:02 -07001324 if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING) {
Kevin Chyn2fefd462017-04-28 12:18:19 -07001325 if (mFingerprintCancelSignal != null) {
1326 mFingerprintCancelSignal.cancel();
1327 mFingerprintCancelSignal = null;
1328 }
Jorim Jaggi86bed402015-08-20 18:20:02 -07001329 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001330 }
Jorim Jaggi86bed402015-08-20 18:20:02 -07001331 if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
1332 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
1333 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001334 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001335
Michael Jurkafff56142012-11-28 16:51:00 -08001336 private boolean isDeviceProvisionedInSettingsDb() {
1337 return Settings.Global.getInt(mContext.getContentResolver(),
1338 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1339 }
1340
Jim Millerbbf1a742012-07-17 18:30:30 -07001341 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -08001342 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001343 @Override
1344 public void onChange(boolean selfChange) {
1345 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -08001346 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001347 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001348 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001349 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001350 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001351 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001352 };
1353
1354 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -07001355 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -08001356 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -07001357
1358 // prevent a race condition between where we check the flag and where we register the
1359 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -08001360 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001361 if (provisioned != mDeviceProvisioned) {
1362 mDeviceProvisioned = provisioned;
1363 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001364 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001365 }
1366 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001367 }
1368
Jim Millerbbf1a742012-07-17 18:30:30 -07001369 /**
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001370 * Update the state whether Keyguard currently has a lockscreen wallpaper.
1371 *
1372 * @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper.
1373 */
1374 public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001375 checkIsHandlerThread();
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001376 if (hasLockscreenWallpaper != mHasLockscreenWallpaper) {
1377 mHasLockscreenWallpaper = hasLockscreenWallpaper;
1378 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1379 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1380 if (cb != null) {
1381 cb.onHasLockscreenWallpaperChanged(hasLockscreenWallpaper);
1382 }
1383 }
1384 }
1385 }
1386
1387 /**
1388 * @return Whether Keyguard has a lockscreen wallpaper.
1389 */
1390 public boolean hasLockscreenWallpaper() {
1391 return mHasLockscreenWallpaper;
1392 }
1393
1394 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001395 * Handle {@link #MSG_DPM_STATE_CHANGED}
1396 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001397 private void handleDevicePolicyManagerStateChanged() {
Adrian Roos733b6632015-08-21 14:32:35 -07001398 updateFingerprintListeningState();
Jim Millerdcb3d842012-08-23 19:18:12 -07001399 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1400 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1401 if (cb != null) {
1402 cb.onDevicePolicyManagerStateChanged();
1403 }
Jim Millerb0304762012-03-13 20:01:25 -07001404 }
1405 }
1406
Jim Millerbbf1a742012-07-17 18:30:30 -07001407 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001408 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -07001409 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001410 private void handleUserSwitching(int userId, IRemoteCallback reply) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001411 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001412 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1413 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001414 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -07001415 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001416 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001417 try {
1418 reply.sendResult(null);
1419 } catch (RemoteException e) {
1420 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001421 }
1422
Jim Millerbbf1a742012-07-17 18:30:30 -07001423 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001424 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
1425 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001426 private void handleUserSwitchComplete(int userId) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001427 for (int i = 0; i < mCallbacks.size(); i++) {
1428 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1429 if (cb != null) {
1430 cb.onUserSwitchComplete(userId);
1431 }
1432 }
1433 }
1434
1435 /**
Jim Miller90873d52013-09-26 18:11:38 -07001436 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
1437 * keyguard crashes sometime after boot, then it will never receive this
1438 * broadcast and hence not handle the event. This method is ultimately called by
1439 * PhoneWindowManager in this case.
1440 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001441 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001442 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -07001443 }
1444
1445 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001446 * Handle {@link #MSG_BOOT_COMPLETED}
1447 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001448 private void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001449 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001450 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001451 for (int i = 0; i < mCallbacks.size(); i++) {
1452 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1453 if (cb != null) {
1454 cb.onBootCompleted();
1455 }
1456 }
1457 }
1458
1459 /**
Jim Miller5ecd8112013-01-09 18:50:26 -08001460 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001461 * destroyed.
1462 */
1463 public boolean hasBootCompleted() {
1464 return mBootCompleted;
1465 }
1466
1467 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001468 * Handle {@link #MSG_DEVICE_PROVISIONED}
1469 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001470 private void handleDeviceProvisioned() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001471 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001472 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1473 if (cb != null) {
1474 cb.onDeviceProvisioned();
1475 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001476 }
Michael Jurkafff56142012-11-28 16:51:00 -08001477 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001478 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -08001479 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
1480 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001481 }
1482 }
1483
Jim Millerbbf1a742012-07-17 18:30:30 -07001484 /**
1485 * Handle {@link #MSG_PHONE_STATE_CHANGED}
1486 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001487 private void handlePhoneStateChanged(String newState) {
Jim Millerc23024d2010-02-24 15:37:00 -08001488 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001489 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
1490 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
1491 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
1492 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
1493 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
1494 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
1495 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001496 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001497 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1498 if (cb != null) {
1499 cb.onPhoneStateChanged(mPhoneState);
1500 }
Jim Millerc23024d2010-02-24 15:37:00 -08001501 }
1502 }
1503
Jim Millerbbf1a742012-07-17 18:30:30 -07001504 /**
1505 * Handle {@link #MSG_RINGER_MODE_CHANGED}
1506 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001507 private void handleRingerModeChange(int mode) {
Jim Miller47088bb2009-11-24 00:40:16 -08001508 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001509 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -07001510 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001511 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1512 if (cb != null) {
1513 cb.onRingerModeChanged(mode);
1514 }
Jim Miller47088bb2009-11-24 00:40:16 -08001515 }
1516 }
1517
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001518 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001519 * Handle {@link #MSG_TIME_UPDATE}
1520 */
1521 private void handleTimeUpdate() {
1522 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001523 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001524 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1525 if (cb != null) {
1526 cb.onTimeChanged();
1527 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001528 }
1529 }
1530
1531 /**
1532 * Handle {@link #MSG_BATTERY_UPDATE}
1533 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001534 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001535 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001536 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
1537 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07001538 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001539 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001540 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1541 if (cb != null) {
1542 cb.onRefreshBatteryInfo(status);
1543 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001544 }
1545 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001546 }
1547
1548 /**
Bill Lin6c7ccab2018-07-05 17:48:49 +08001549 * Handle Telephony status during Boot for CarrierText display policy
1550 */
1551 @VisibleForTesting
1552 void updateTelephonyCapable(boolean capable){
1553 if (capable == mTelephonyCapable) {
1554 return;
1555 }
1556 mTelephonyCapable = capable;
1557 for (WeakReference<KeyguardUpdateMonitorCallback> ref : mCallbacks) {
1558 KeyguardUpdateMonitorCallback cb = ref.get();
1559 if (cb != null) {
1560 cb.onTelephonyCapable(mTelephonyCapable);
1561 }
1562 }
1563 }
1564
1565 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001566 * Handle {@link #MSG_SIM_STATE_CHANGE}
1567 */
Lucas Dupin5e0f0d22018-02-26 13:32:16 -08001568 @VisibleForTesting
Adrian Roos30a2ae62018-04-25 19:09:50 +02001569 void handleSimStateChange(int subId, int slotId, State state) {
1570 checkIsHandlerThread();
Jim Miller52a61332014-11-12 19:29:51 -08001571 if (DEBUG_SIM_STATES) {
1572 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
1573 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001574 }
1575
Lucas Dupin0b196c62018-12-05 20:03:53 -08001576 boolean becameAbsent = false;
Wink Savillea54bf652014-12-11 13:37:50 -08001577 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08001578 Log.w(TAG, "invalid subId in handleSimStateChange()");
Bill Lin6c7ccab2018-07-05 17:48:49 +08001579 /* Only handle No SIM(ABSENT) due to handleServiceStateChange() handle other case */
1580 if (state == State.ABSENT) {
1581 updateTelephonyCapable(true);
Lucas Dupin0b196c62018-12-05 20:03:53 -08001582 // Even though the subscription is not valid anymore, we need to notify that the
1583 // SIM card was removed so we can update the UI.
1584 becameAbsent = true;
Brad Ebinger4b2f6e22018-12-20 21:11:44 -08001585 for (SimData data : mSimDatas.values()) {
1586 // Set the SIM state of all SimData associated with that slot to ABSENT se we
1587 // do not move back into PIN/PUK locked and not detect the change below.
1588 if (data.slotId == slotId) {
1589 data.simState = State.ABSENT;
1590 }
1591 }
Lucas Dupin0b196c62018-12-05 20:03:53 -08001592 } else {
1593 return;
Bill Lin6c7ccab2018-07-05 17:48:49 +08001594 }
Jim Miller52a61332014-11-12 19:29:51 -08001595 }
1596
1597 SimData data = mSimDatas.get(subId);
1598 final boolean changed;
1599 if (data == null) {
1600 data = new SimData(state, slotId, subId);
1601 mSimDatas.put(subId, data);
1602 changed = true; // no data yet; force update
1603 } else {
1604 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
1605 data.simState = state;
1606 data.subId = subId;
1607 data.slotId = slotId;
1608 }
Lucas Dupin0b196c62018-12-05 20:03:53 -08001609 if ((changed || becameAbsent) && state != State.UNKNOWN) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001610 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001611 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1612 if (cb != null) {
Jim Miller52a61332014-11-12 19:29:51 -08001613 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07001614 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001615 }
1616 }
1617 }
1618
Jim Millerbbf1a742012-07-17 18:30:30 -07001619 /**
Etan Cohen47051d82015-07-06 16:19:04 -07001620 * Handle {@link #MSG_SERVICE_STATE_CHANGE}
1621 */
Bill Lin6c7ccab2018-07-05 17:48:49 +08001622 @VisibleForTesting
1623 void handleServiceStateChange(int subId, ServiceState serviceState) {
Etan Cohen47051d82015-07-06 16:19:04 -07001624 if (DEBUG) {
1625 Log.d(TAG,
1626 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
1627 }
1628
1629 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1630 Log.w(TAG, "invalid subId in handleServiceStateChange()");
1631 return;
Bill Lin6c7ccab2018-07-05 17:48:49 +08001632 } else {
1633 updateTelephonyCapable(true);
Etan Cohen47051d82015-07-06 16:19:04 -07001634 }
1635
1636 mServiceStates.put(subId, serviceState);
1637
1638 for (int j = 0; j < mCallbacks.size(); j++) {
1639 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
1640 if (cb != null) {
1641 cb.onRefreshCarrierInfo();
1642 }
1643 }
1644 }
1645
Lucas Dupinf8463ee2018-06-11 16:18:15 -07001646 public boolean isKeyguardVisible() {
1647 return mKeyguardIsVisible;
1648 }
1649
Etan Cohen47051d82015-07-06 16:19:04 -07001650 /**
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001651 * Notifies that the visibility state of Keyguard has changed.
1652 *
1653 * <p>Needs to be called from the main thread.
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001654 */
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001655 public void onKeyguardVisibilityChanged(boolean showing) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001656 checkIsHandlerThread();
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001657 if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
1658 mKeyguardIsVisible = showing;
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001659 for (int i = 0; i < mCallbacks.size(); i++) {
1660 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1661 if (cb != null) {
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001662 cb.onKeyguardVisibilityChangedRaw(showing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001663 }
1664 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001665 updateFingerprintListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001666 }
1667
Brian Colonna7fce3802013-09-17 15:51:32 -04001668 /**
Selim Cinek1fcafc42015-07-20 14:39:25 -07001669 * Handle {@link #MSG_KEYGUARD_RESET}
1670 */
1671 private void handleKeyguardReset() {
1672 if (DEBUG) Log.d(TAG, "handleKeyguardReset");
Adrian Roosf6d51ac2015-09-02 13:26:25 -07001673 updateFingerprintListeningState();
Jorim Jaggi031f7952016-09-01 16:39:26 -07001674 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1675 }
1676
1677 private boolean resolveNeedsSlowUnlockTransition() {
1678 if (mUserManager.isUserUnlocked(getCurrentUser())) {
1679 return false;
1680 }
1681 Intent homeIntent = new Intent(Intent.ACTION_MAIN)
1682 .addCategory(Intent.CATEGORY_HOME);
1683 ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(homeIntent,
1684 0 /* flags */);
1685 return FALLBACK_HOME_COMPONENT.equals(resolveInfo.getComponentInfo().getComponentName());
Selim Cinek1fcafc42015-07-20 14:39:25 -07001686 }
1687
1688 /**
Adrian Roosb6011622014-05-14 15:52:53 +02001689 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
1690 * @see #sendKeyguardBouncerChanged(boolean)
1691 */
1692 private void handleKeyguardBouncerChanged(int bouncer) {
1693 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
1694 boolean isBouncer = (bouncer == 1);
1695 mBouncer = isBouncer;
1696 for (int i = 0; i < mCallbacks.size(); i++) {
1697 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1698 if (cb != null) {
1699 cb.onKeyguardBouncerChanged(isBouncer);
1700 }
1701 }
Jorim Jaggi3cf7eef2015-09-10 14:36:19 -07001702 updateFingerprintListeningState();
Adrian Roosb6011622014-05-14 15:52:53 +02001703 }
1704
1705 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04001706 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
1707 */
1708 private void handleReportEmergencyCallAction() {
1709 for (int i = 0; i < mCallbacks.size(); i++) {
1710 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1711 if (cb != null) {
1712 cb.onEmergencyCallAction();
1713 }
1714 }
1715 }
1716
Lucas Dupin4272f442018-01-13 22:00:35 -08001717 private boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001718 final boolean nowPluggedIn = current.isPluggedIn();
1719 final boolean wasPluggedIn = old.isPluggedIn();
Lucas Dupin4272f442018-01-13 22:00:35 -08001720 final boolean stateChangedWhilePluggedIn = wasPluggedIn && nowPluggedIn
Jim Miller16464b82011-10-20 21:10:13 -07001721 && (old.status != current.status);
1722
1723 // change in plug state is always interesting
1724 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001725 return true;
1726 }
1727
Lucas Dupin3fcdd472018-01-19 19:06:45 -08001728 // change in battery level
1729 if (old.level != current.level) {
Jim Miller16464b82011-10-20 21:10:13 -07001730 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001731 }
Adrian Roos76dc5a52015-07-21 16:20:36 -07001732
1733 // change in charging current while plugged in
Adrian Roos0c859ae2015-11-23 16:47:50 -08001734 if (nowPluggedIn && current.maxChargingWattage != old.maxChargingWattage) {
Adrian Roos76dc5a52015-07-21 16:20:36 -07001735 return true;
1736 }
1737
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001738 return false;
1739 }
1740
1741 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001742 * Remove the given observer's callback.
1743 *
Jim Miller6212cc02012-09-05 17:35:31 -07001744 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001745 */
Jim Miller6212cc02012-09-05 17:35:31 -07001746 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001747 checkIsHandlerThread();
Jim Miller6212cc02012-09-05 17:35:31 -07001748 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
1749 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1750 if (mCallbacks.get(i).get() == callback) {
1751 mCallbacks.remove(i);
1752 }
1753 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001754 }
1755
1756 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001757 * Register to receive notifications about general keyguard information
1758 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07001759 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001760 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001761 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001762 checkIsHandlerThread();
Jim Miller6212cc02012-09-05 17:35:31 -07001763 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
1764 // Prevent adding duplicate callbacks
1765 for (int i = 0; i < mCallbacks.size(); i++) {
1766 if (mCallbacks.get(i).get() == callback) {
1767 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
1768 new Exception("Called by"));
1769 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07001770 }
1771 }
Jim Miller6212cc02012-09-05 17:35:31 -07001772 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
1773 removeCallback(null); // remove unused references
1774 sendUpdates(callback);
1775 }
1776
Evan Rosky18396452016-07-27 15:19:37 -07001777 public boolean isSwitchingUser() {
1778 return mSwitchingUser;
1779 }
1780
Adrian Roos30a2ae62018-04-25 19:09:50 +02001781 @AnyThread
Evan Rosky18396452016-07-27 15:19:37 -07001782 public void setSwitchingUser(boolean switching) {
1783 mSwitchingUser = switching;
Selim Cinekbbe19242017-12-08 15:42:08 -08001784 // Since this comes in on a binder thread, we need to post if first
1785 mHandler.post(mUpdateFingerprintListeningState);
Evan Rosky18396452016-07-27 15:19:37 -07001786 }
1787
Jim Miller6212cc02012-09-05 17:35:31 -07001788 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
1789 // Notify listener of the current state
1790 callback.onRefreshBatteryInfo(mBatteryStatus);
1791 callback.onTimeChanged();
1792 callback.onRingerModeChanged(mRingMode);
1793 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05001794 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07001795 callback.onClockVisibilityChanged();
Lucas Dupin16cfe452018-02-08 13:14:50 -08001796 callback.onKeyguardVisibilityChangedRaw(mKeyguardIsVisible);
Bill Lin6c7ccab2018-07-05 17:48:49 +08001797 callback.onTelephonyCapable(mTelephonyCapable);
Jim Miller52a61332014-11-12 19:29:51 -08001798 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
1799 final SimData state = data.getValue();
1800 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
1801 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001802 }
1803
Selim Cinek1fcafc42015-07-20 14:39:25 -07001804 public void sendKeyguardReset() {
1805 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
1806 }
1807
Adrian Roosb6011622014-05-14 15:52:53 +02001808 /**
1809 * @see #handleKeyguardBouncerChanged(int)
1810 */
1811 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
1812 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
1813 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
1814 message.arg1 = showingBouncer ? 1 : 0;
1815 message.sendToTarget();
1816 }
1817
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001818 /**
Jim Miller90d5d462011-11-17 16:57:01 -08001819 * 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 -08001820 * have the information earlier than waiting for the intent
1821 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08001822 *
1823 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
1824 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001825 */
Adrian Roos30a2ae62018-04-25 19:09:50 +02001826 @MainThread
Jim Miller52a61332014-11-12 19:29:51 -08001827 public void reportSimUnlocked(int subId) {
1828 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
Sanket Padawe7e460252017-03-10 16:18:20 -08001829 int slotId = SubscriptionManager.getSlotIndex(subId);
Jim Miller52a61332014-11-12 19:29:51 -08001830 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001831 }
1832
Brian Colonna7fce3802013-09-17 15:51:32 -04001833 /**
1834 * Report that the emergency call button has been pressed and the emergency dialer is
1835 * about to be displayed.
1836 *
1837 * @param bypassHandler runs immediately.
1838 *
1839 * NOTE: Must be called from UI thread if bypassHandler == true.
1840 */
1841 public void reportEmergencyCallAction(boolean bypassHandler) {
1842 if (!bypassHandler) {
1843 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
1844 } else {
Adrian Roos30a2ae62018-04-25 19:09:50 +02001845 checkIsHandlerThread();
Brian Colonna7fce3802013-09-17 15:51:32 -04001846 handleReportEmergencyCallAction();
1847 }
1848 }
1849
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001850 /**
1851 * @return Whether the device is provisioned (whether they have gone through
1852 * the setup wizard)
1853 */
1854 public boolean isDeviceProvisioned() {
1855 return mDeviceProvisioned;
1856 }
1857
Kensuke Matsui21d1bf12017-03-14 13:27:20 +09001858 public ServiceState getServiceState(int subId) {
1859 return mServiceStates.get(subId);
1860 }
1861
Jim Millerf41fc962014-06-18 16:33:51 -07001862 public void clearFingerprintRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07001863 mUserFingerprintAuthenticated.clear();
Kevin Chyn3fdbbf82017-05-06 15:11:53 -07001864 mTrustManager.clearAllFingerprints();
Jim Millerf41fc962014-06-18 16:33:51 -07001865 }
1866
Jim Miller52a61332014-11-12 19:29:51 -08001867 public boolean isSimPinVoiceSecure() {
1868 // TODO: only count SIMs that handle voice
1869 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07001870 }
1871
1872 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08001873 // True if any SIM is pin secure
1874 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
1875 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
1876 }
1877 return false;
1878 }
1879
Jason Monk9ff69bd2014-12-02 16:43:17 -05001880 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08001881 if (mSimDatas.containsKey(subId)) {
1882 return mSimDatas.get(subId).simState;
1883 } else {
1884 return State.UNKNOWN;
1885 }
1886 }
1887
Winson Chungaa357452017-10-31 11:35:30 -07001888 private final SysUiTaskStackChangeListener
1889 mTaskStackListener = new SysUiTaskStackChangeListener() {
Kevin Chyn2fefd462017-04-28 12:18:19 -07001890 @Override
1891 public void onTaskStackChangedBackground() {
1892 try {
1893 ActivityManager.StackInfo info = ActivityManager.getService().getStackInfo(
Wale Ogunwale68278562017-09-23 17:13:55 -07001894 WINDOWING_MODE_UNDEFINED, ACTIVITY_TYPE_ASSISTANT);
Kevin Chyn2fefd462017-04-28 12:18:19 -07001895 if (info == null) {
1896 return;
1897 }
1898 mHandler.sendMessage(mHandler.obtainMessage(MSG_ASSISTANT_STACK_CHANGED,
1899 info.visible));
1900 } catch (RemoteException e) {
1901 Log.e(TAG, "unable to check task stack", e);
1902 }
1903 }
1904 };
1905
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001906 /**
Richard Choue0381b82018-04-24 03:48:59 +00001907 * @return true if and only if the state has changed for the specified {@code slotId}
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001908 */
Richard Choue0381b82018-04-24 03:48:59 +00001909 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08001910
1911 // This is awful. It exists because there are two APIs for getting the SIM status
1912 // that don't return the complete set of values and have different types. In Keyguard we
1913 // need IccCardConstants, but TelephonyManager would only give us
1914 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08001915 final TelephonyManager tele = TelephonyManager.from(mContext);
Richard Choue0381b82018-04-24 03:48:59 +00001916 int simState = tele.getSimState(slotId);
1917 State state;
1918 try {
1919 state = State.intToState(simState);
1920 } catch(IllegalArgumentException ex) {
1921 Log.w(TAG, "Unknown sim state: " + simState);
1922 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05001923 }
Richard Choue0381b82018-04-24 03:48:59 +00001924 SimData data = mSimDatas.get(subId);
1925 final boolean changed;
1926 if (data == null) {
1927 data = new SimData(state, slotId, subId);
1928 mSimDatas.put(subId, data);
1929 changed = true; // no data yet; force update
1930 } else {
1931 changed = data.simState != state;
1932 data.simState = state;
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001933 }
Richard Choue0381b82018-04-24 03:48:59 +00001934 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07001935 }
1936
1937 public static boolean isSimPinSecure(IccCardConstants.State state) {
1938 final IccCardConstants.State simState = state;
1939 return (simState == IccCardConstants.State.PIN_REQUIRED
1940 || simState == IccCardConstants.State.PUK_REQUIRED
1941 || simState == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07001942 }
Jim Miller8f09fd22013-03-14 19:04:28 -07001943
1944 public DisplayClientState getCachedDisplayClientState() {
1945 return mDisplayClientState;
1946 }
Jim Miller20daffd2013-10-07 14:59:53 -07001947
1948 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
1949 // (KeyguardViewMediator, KeyguardHostView)
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001950 public void dispatchStartedWakingUp() {
1951 synchronized (this) {
1952 mDeviceInteractive = true;
1953 }
1954 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
1955 }
1956
Jorim Jaggi95e40382015-09-16 15:53:42 -07001957 public void dispatchStartedGoingToSleep(int why) {
1958 mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
1959 }
1960
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001961 public void dispatchFinishedGoingToSleep(int why) {
1962 synchronized(this) {
1963 mDeviceInteractive = false;
1964 }
1965 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
1966 }
1967
Jim Miller20daffd2013-10-07 14:59:53 -07001968 public void dispatchScreenTurnedOn() {
1969 synchronized (this) {
1970 mScreenOn = true;
1971 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001972 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
Jim Miller20daffd2013-10-07 14:59:53 -07001973 }
1974
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001975 public void dispatchScreenTurnedOff() {
Jim Miller20daffd2013-10-07 14:59:53 -07001976 synchronized(this) {
1977 mScreenOn = false;
1978 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001979 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
Jim Miller20daffd2013-10-07 14:59:53 -07001980 }
1981
Selim Cinek99415392016-09-09 14:58:41 -07001982 public void dispatchDreamingStarted() {
1983 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 1, 0));
1984 }
1985
1986 public void dispatchDreamingStopped() {
1987 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 0, 0));
1988 }
1989
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001990 public boolean isDeviceInteractive() {
1991 return mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -07001992 }
Jim Miller52a61332014-11-12 19:29:51 -08001993
Jorim Jaggi95e40382015-09-16 15:53:42 -07001994 public boolean isGoingToSleep() {
1995 return mGoingToSleep;
1996 }
1997
Jim Miller52a61332014-11-12 19:29:51 -08001998 /**
1999 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
2000 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08002001 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08002002 */
2003 public int getNextSubIdForState(State state) {
2004 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08002005 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08002006 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
2007 for (int i = 0; i < list.size(); i++) {
2008 final SubscriptionInfo info = list.get(i);
2009 final int id = info.getSubscriptionId();
Sanket Padawe7e460252017-03-10 16:18:20 -08002010 int slotId = SubscriptionManager.getSlotIndex(id);
Jim Miller52a61332014-11-12 19:29:51 -08002011 if (state == getSimState(id) && bestSlotId > slotId ) {
2012 resultId = id;
2013 bestSlotId = slotId;
2014 }
2015 }
2016 return resultId;
2017 }
2018
2019 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
2020 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
2021 for (int i = 0; i < list.size(); i++) {
2022 SubscriptionInfo info = list.get(i);
2023 if (subId == info.getSubscriptionId()) return info;
2024 }
2025 return null; // not found
2026 }
Jason Monkab525272015-07-13 17:02:49 -04002027
Alex Chauff7653d2018-02-01 17:18:08 +00002028 /**
2029 * @return a cached version of DevicePolicyManager.isLogoutEnabled()
2030 */
2031 public boolean isLogoutEnabled() {
2032 return mLogoutEnabled;
2033 }
2034
2035 private void updateLogoutEnabled() {
Adrian Roos30a2ae62018-04-25 19:09:50 +02002036 checkIsHandlerThread();
Alex Chauff7653d2018-02-01 17:18:08 +00002037 boolean logoutEnabled = mDevicePolicyManager.isLogoutEnabled();
2038 if (mLogoutEnabled != logoutEnabled) {
2039 mLogoutEnabled = logoutEnabled;
2040 for (int i = 0; i < mCallbacks.size(); i++) {
2041 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
2042 if (cb != null) {
2043 cb.onLogoutEnabledChanged();
2044 }
2045 }
2046 }
2047 }
2048
Adrian Roos30a2ae62018-04-25 19:09:50 +02002049 private void checkIsHandlerThread() {
2050 if (sDisableHandlerCheckForTesting) {
2051 return;
2052 }
2053 if (!mHandler.getLooper().isCurrentThread()) {
2054 Log.wtf(TAG, "must call on mHandler's thread "
2055 + mHandler.getLooper().getThread() + ", not " + Thread.currentThread());
2056 }
2057 }
2058
2059 /**
2060 * Turn off the handler check for testing.
2061 *
2062 * This is necessary because currently tests are not too careful about which thread they call
2063 * into this class on.
2064 *
2065 * Note that this must be called before scheduling any work involving KeyguardUpdateMonitor
2066 * instances.
2067 *
2068 * TODO: fix the tests and remove this.
2069 */
2070 @VisibleForTesting
2071 public static void disableHandlerCheckForTesting(Instrumentation instrumentation) {
2072 Preconditions.checkNotNull(instrumentation, "Must only call this method in tests!");
2073 // Don't need synchronization here *if* the callers follow the contract and call this only
2074 // before scheduling work for KeyguardUpdateMonitor on other threads, because the scheduling
2075 // of that work forces a happens-before relationship.
2076 sDisableHandlerCheckForTesting = true;
2077 }
2078
Jason Monkab525272015-07-13 17:02:49 -04002079 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2080 pw.println("KeyguardUpdateMonitor state:");
2081 pw.println(" SIM States:");
2082 for (SimData data : mSimDatas.values()) {
2083 pw.println(" " + data.toString());
2084 }
2085 pw.println(" Subs:");
2086 if (mSubscriptionInfo != null) {
2087 for (int i = 0; i < mSubscriptionInfo.size(); i++) {
2088 pw.println(" " + mSubscriptionInfo.get(i));
2089 }
2090 }
2091 pw.println(" Service states:");
2092 for (int subId : mServiceStates.keySet()) {
2093 pw.println(" " + subId + "=" + mServiceStates.get(subId));
2094 }
Jim Millerd72d5ac2015-09-29 18:55:32 -07002095 if (mFpm != null && mFpm.isHardwareDetected()) {
2096 final int userId = ActivityManager.getCurrentUser();
2097 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
2098 pw.println(" Fingerprint state (user=" + userId + ")");
2099 pw.println(" allowed=" + isUnlockingWithFingerprintAllowed());
2100 pw.println(" auth'd=" + mUserFingerprintAuthenticated.get(userId));
2101 pw.println(" authSinceBoot="
2102 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
2103 pw.println(" disabled(DPM)=" + isFingerprintDisabled(userId));
2104 pw.println(" possible=" + isUnlockWithFingerprintPossible(userId));
2105 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
Jim Millerd72d5ac2015-09-29 18:55:32 -07002106 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
2107 }
Jason Monkab525272015-07-13 17:02:49 -04002108 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08002109}