blob: f8d1bfbc18be66cbf3f9589276a6d6977a2fee06 [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
Jorim Jaggidadafd42016-09-30 07:20:25 -070019import static android.content.Intent.ACTION_USER_UNLOCKED;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070020import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
21import static android.os.BatteryManager.BATTERY_STATUS_FULL;
22import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
23import static android.os.BatteryManager.EXTRA_HEALTH;
24import static android.os.BatteryManager.EXTRA_LEVEL;
25import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
26import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
27import static android.os.BatteryManager.EXTRA_PLUGGED;
28import static android.os.BatteryManager.EXTRA_STATUS;
29
Jorim Jaggiccdfa932015-04-13 16:29:48 -070030import android.app.ActivityManager;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020031import android.app.AlarmManager;
Jim Miller8f09fd22013-03-14 19:04:28 -070032import android.app.PendingIntent;
Sudheer Shanka2c4522c2016-08-27 20:53:28 -070033import android.app.UserSwitchObserver;
Jim Millerb0304762012-03-13 20:01:25 -070034import android.app.admin.DevicePolicyManager;
Adrian Roos46842d92014-03-27 14:58:03 +010035import android.app.trust.TrustManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080036import android.content.BroadcastReceiver;
Jorim Jaggi031f7952016-09-01 16:39:26 -070037import android.content.ComponentName;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080038import android.content.Context;
39import android.content.Intent;
40import android.content.IntentFilter;
Jorim Jaggi031f7952016-09-01 16:39:26 -070041import android.content.pm.PackageManager;
42import android.content.pm.ResolveInfo;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080043import android.database.ContentObserver;
Jim Miller8f09fd22013-03-14 19:04:28 -070044import android.graphics.Bitmap;
Jorim Jaggi86bed402015-08-20 18:20:02 -070045import android.hardware.fingerprint.FingerprintManager;
46import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
47import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
Jim Miller47088bb2009-11-24 00:40:16 -080048import android.media.AudioManager;
Jim Miller79a444a2011-02-15 15:02:11 -080049import android.os.BatteryManager;
Jim Miller9f0753f2015-03-23 23:59:22 -070050import android.os.CancellationSignal;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080051import android.os.Handler;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070052import android.os.IRemoteCallback;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080053import android.os.Message;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070054import android.os.RemoteException;
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -070055import android.os.SystemClock;
Nick Desaulniers1d396752016-07-25 15:05:33 -070056import android.os.Trace;
Amith Yamasanie8e93a12013-05-09 18:12:30 -070057import android.os.UserHandle;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070058import android.os.UserManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080059import android.provider.Settings;
Etan Cohen47051d82015-07-06 16:19:04 -070060import android.telephony.ServiceState;
Jim Miller52a61332014-11-12 19:29:51 -080061import android.telephony.SubscriptionInfo;
Jim Miller52a61332014-11-12 19:29:51 -080062import android.telephony.SubscriptionManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -080063import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Jim Millerc23024d2010-02-24 15:37:00 -080064import android.telephony.TelephonyManager;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -070065import android.util.ArraySet;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080066import android.util.Log;
Adrian Roos46842d92014-03-27 14:58:03 +010067import android.util.SparseBooleanArray;
Jorim Jaggi9f743032015-05-04 15:22:40 -070068import android.util.SparseIntArray;
Adrian Roos46842d92014-03-27 14:58:03 +010069
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080070import com.google.android.collect.Lists;
71
Jorim Jaggi86bed402015-08-20 18:20:02 -070072import com.android.internal.telephony.IccCardConstants;
73import com.android.internal.telephony.IccCardConstants.State;
74import com.android.internal.telephony.PhoneConstants;
75import com.android.internal.telephony.TelephonyIntents;
Adrian Roosb5e47222015-08-14 15:53:06 -070076import com.android.internal.widget.LockPatternUtils;
Jorim Jaggi86bed402015-08-20 18:20:02 -070077
Jason Monkab525272015-07-13 17:02:49 -040078import java.io.FileDescriptor;
79import java.io.PrintWriter;
Jim Millerdcb3d842012-08-23 19:18:12 -070080import java.lang.ref.WeakReference;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080081import java.util.ArrayList;
Jim Miller52a61332014-11-12 19:29:51 -080082import java.util.HashMap;
83import java.util.List;
84import java.util.Map.Entry;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080085
86/**
87 * Watches for updates that may be interesting to the keyguard, and provides
88 * the up to date information as well as a registration for callbacks that care
89 * to be updated.
90 *
91 * Note: under time crunch, this has been extended to include some stuff that
92 * doesn't really belong here. see {@link #handleBatteryUpdate} where it shutdowns
Jim Miller258341c2012-08-30 16:50:10 -070093 * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()}
94 * and {@link #clearFailedUnlockAttempts()}. Maybe we should rename this 'KeyguardContext'...
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080095 */
Adrian Roos46842d92014-03-27 14:58:03 +010096public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080097
Jim Millerbbf1a742012-07-17 18:30:30 -070098 private static final String TAG = "KeyguardUpdateMonitor";
Jorim Jaggi5cf17872014-03-26 18:31:48 +010099 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller52a61332014-11-12 19:29:51 -0800100 private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
Jim Millerbbf1a742012-07-17 18:30:30 -0700101 private static final int LOW_BATTERY_THRESHOLD = 20;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800102
Jorim Jaggie7b12522014-08-06 16:41:21 +0200103 private static final String ACTION_FACE_UNLOCK_STARTED
104 = "com.android.facelock.FACE_UNLOCK_STARTED";
105 private static final String ACTION_FACE_UNLOCK_STOPPED
106 = "com.android.facelock.FACE_UNLOCK_STOPPED";
107
Jim Millerbbf1a742012-07-17 18:30:30 -0700108 // Callback messages
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800109 private static final int MSG_TIME_UPDATE = 301;
110 private static final int MSG_BATTERY_UPDATE = 302;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800111 private static final int MSG_SIM_STATE_CHANGE = 304;
Jim Miller47088bb2009-11-24 00:40:16 -0800112 private static final int MSG_RINGER_MODE_CHANGED = 305;
Jim Millerc23024d2010-02-24 15:37:00 -0800113 private static final int MSG_PHONE_STATE_CHANGED = 306;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700114 private static final int MSG_DEVICE_PROVISIONED = 308;
Jim Miller57375342012-09-09 15:20:31 -0700115 private static final int MSG_DPM_STATE_CHANGED = 309;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500116 private static final int MSG_USER_SWITCHING = 310;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700117 private static final int MSG_KEYGUARD_RESET = 312;
Jim Millerf41fc962014-06-18 16:33:51 -0700118 private static final int MSG_BOOT_COMPLETED = 313;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500119 private static final int MSG_USER_SWITCH_COMPLETE = 314;
Jim Millerf41fc962014-06-18 16:33:51 -0700120 private static final int MSG_USER_INFO_CHANGED = 317;
121 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700122 private static final int MSG_STARTED_WAKING_UP = 319;
123 private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700124 private static final int MSG_STARTED_GOING_TO_SLEEP = 321;
Adrian Roosb6011622014-05-14 15:52:53 +0200125 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700126 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
127 private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
Jason Monk052082c2015-06-11 11:35:23 -0400128 private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
Etan Cohen47051d82015-07-06 16:19:04 -0700129 private static final int MSG_SERVICE_STATE_CHANGE = 330;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700130 private static final int MSG_SCREEN_TURNED_ON = 331;
131 private static final int MSG_SCREEN_TURNED_OFF = 332;
Selim Cinek99415392016-09-09 14:58:41 -0700132 private static final int MSG_DREAMING_STATE_CHANGED = 333;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700133 private static final int MSG_USER_UNLOCKED = 334;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800134
Jorim Jaggi86bed402015-08-20 18:20:02 -0700135 /** Fingerprint state: Not listening to fingerprint. */
136 private static final int FINGERPRINT_STATE_STOPPED = 0;
137
138 /** Fingerprint state: Listening. */
139 private static final int FINGERPRINT_STATE_RUNNING = 1;
140
141 /**
142 * Fingerprint state: Cancelling and waiting for the confirmation from FingerprintService to
143 * send us the confirmation that cancellation has happened.
144 */
145 private static final int FINGERPRINT_STATE_CANCELLING = 2;
146
147 /**
148 * Fingerprint state: During cancelling we got another request to start listening, so when we
149 * receive the cancellation done signal, we should start listening again.
150 */
151 private static final int FINGERPRINT_STATE_CANCELLING_RESTARTING = 3;
152
Adrian Roos0c859ae2015-11-23 16:47:50 -0800153 private static final int DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT = 5000000;
154
Jorim Jaggi031f7952016-09-01 16:39:26 -0700155 private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName(
156 "com.android.settings", "com.android.settings.FallbackHome");
157
Jim Millerdcb3d842012-08-23 19:18:12 -0700158 private static KeyguardUpdateMonitor sInstance;
159
Jim Millerbbf1a742012-07-17 18:30:30 -0700160 private final Context mContext;
Jim Miller52a61332014-11-12 19:29:51 -0800161 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
Etan Cohen47051d82015-07-06 16:19:04 -0700162 HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700163
Jim Millerbbf1a742012-07-17 18:30:30 -0700164 private int mRingMode;
165 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400166 private boolean mKeyguardIsVisible;
Jorim Jaggi71448a72015-08-18 19:49:04 -0700167
168 /**
169 * If true, fingerprint was already authenticated and we don't need to start listening again
170 * until the Keyguard has been dismissed.
171 */
172 private boolean mFingerprintAlreadyAuthenticated;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700173 private boolean mGoingToSleep;
Adrian Roosb6011622014-05-14 15:52:53 +0200174 private boolean mBouncer;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800175 private boolean mBootCompleted;
Jorim Jaggi031f7952016-09-01 16:39:26 -0700176 private boolean mNeedsSlowUnlockTransition;
Jorim Jaggid11d1a92016-08-16 16:02:32 -0700177 private boolean mHasLockscreenWallpaper;
Jim Millerbbf1a742012-07-17 18:30:30 -0700178
Jim Millerdcb3d842012-08-23 19:18:12 -0700179 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700180 private boolean mDeviceProvisioned;
181
Jim Millerdcb3d842012-08-23 19:18:12 -0700182 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700183 private BatteryStatus mBatteryStatus;
184
Jim Millerdcb3d842012-08-23 19:18:12 -0700185 // Password attempts
Jorim Jaggi9f743032015-05-04 15:22:40 -0700186 private SparseIntArray mFailedAttempts = new SparseIntArray();
Brian Colonnacc4104f2012-10-09 17:50:46 -0400187
Rakesh Iyera7aa4d62016-01-19 17:27:23 -0800188 private final StrongAuthTracker mStrongAuthTracker;
Jim Millerbbf1a742012-07-17 18:30:30 -0700189
Jim Miller6212cc02012-09-05 17:35:31 -0700190 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700191 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800192 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700193
Brian Colonnaa5239892013-04-15 11:45:40 -0400194 private boolean mSwitchingUser;
195
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700196 private boolean mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -0700197 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800198 private SubscriptionManager mSubscriptionManager;
199 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700200 private TrustManager mTrustManager;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700201 private UserManager mUserManager;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700202 private int mFingerprintRunningState = FINGERPRINT_STATE_STOPPED;
Michal Karpinskic52f8672016-11-18 11:32:45 +0000203 private LockPatternUtils mLockPatternUtils;
Jim Miller20daffd2013-10-07 14:59:53 -0700204
Jim Millerbbf1a742012-07-17 18:30:30 -0700205 private final Handler mHandler = new Handler() {
206 @Override
207 public void handleMessage(Message msg) {
208 switch (msg.what) {
209 case MSG_TIME_UPDATE:
210 handleTimeUpdate();
211 break;
212 case MSG_BATTERY_UPDATE:
213 handleBatteryUpdate((BatteryStatus) msg.obj);
214 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700215 case MSG_SIM_STATE_CHANGE:
Jim Miller52a61332014-11-12 19:29:51 -0800216 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700217 break;
218 case MSG_RINGER_MODE_CHANGED:
219 handleRingerModeChange(msg.arg1);
220 break;
221 case MSG_PHONE_STATE_CHANGED:
Adrian Roosb6011622014-05-14 15:52:53 +0200222 handlePhoneStateChanged((String) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700223 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700224 case MSG_DEVICE_PROVISIONED:
225 handleDeviceProvisioned();
226 break;
227 case MSG_DPM_STATE_CHANGED:
228 handleDevicePolicyManagerStateChanged();
229 break;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500230 case MSG_USER_SWITCHING:
Adrian Roosb6011622014-05-14 15:52:53 +0200231 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
Chris Wrenf41c61b2012-11-29 15:19:54 -0500232 break;
233 case MSG_USER_SWITCH_COMPLETE:
234 handleUserSwitchComplete(msg.arg1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700235 break;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700236 case MSG_KEYGUARD_RESET:
237 handleKeyguardReset();
238 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200239 case MSG_KEYGUARD_BOUNCER_CHANGED:
240 handleKeyguardBouncerChanged(msg.arg1);
241 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800242 case MSG_BOOT_COMPLETED:
243 handleBootCompleted();
244 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700245 case MSG_USER_INFO_CHANGED:
246 handleUserInfoChanged(msg.arg1);
247 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400248 case MSG_REPORT_EMERGENCY_CALL_ACTION:
249 handleReportEmergencyCallAction();
250 break;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700251 case MSG_STARTED_GOING_TO_SLEEP:
252 handleStartedGoingToSleep(msg.arg1);
253 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700254 case MSG_FINISHED_GOING_TO_SLEEP:
255 handleFinishedGoingToSleep(msg.arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700256 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700257 case MSG_STARTED_WAKING_UP:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700258 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_STARTED_WAKING_UP");
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700259 handleStartedWakingUp();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700260 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -0700261 break;
Jorim Jaggie7b12522014-08-06 16:41:21 +0200262 case MSG_FACE_UNLOCK_STATE_CHANGED:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700263 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_FACE_UNLOCK_STATE_CHANGED");
Adrian Roos4a410172014-08-20 17:41:44 +0200264 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
Nick Desaulniers1d396752016-07-25 15:05:33 -0700265 Trace.endSection();
Jorim Jaggie7b12522014-08-06 16:41:21 +0200266 break;
Jim Miller52a61332014-11-12 19:29:51 -0800267 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
268 handleSimSubscriptionInfoChanged();
269 break;
Jason Monk052082c2015-06-11 11:35:23 -0400270 case MSG_AIRPLANE_MODE_CHANGED:
271 handleAirplaneModeChanged();
272 break;
Etan Cohen47051d82015-07-06 16:19:04 -0700273 case MSG_SERVICE_STATE_CHANGE:
274 handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
275 break;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700276 case MSG_SCREEN_TURNED_ON:
277 handleScreenTurnedOn();
278 break;
279 case MSG_SCREEN_TURNED_OFF:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700280 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_SCREEN_TURNED_ON");
Jorim Jaggif1518da2015-07-30 11:56:36 -0700281 handleScreenTurnedOff();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700282 Trace.endSection();
Jorim Jaggif1518da2015-07-30 11:56:36 -0700283 break;
Selim Cinek99415392016-09-09 14:58:41 -0700284 case MSG_DREAMING_STATE_CHANGED:
285 handleDreamingStateChanged(msg.arg1);
286 break;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700287 case MSG_USER_UNLOCKED:
288 handleUserUnlocked();
289 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700290 }
291 }
292 };
293
Wink Savilled09c4ca2014-11-22 10:08:16 -0800294 private OnSubscriptionsChangedListener mSubscriptionListener =
295 new OnSubscriptionsChangedListener() {
Jim Miller52a61332014-11-12 19:29:51 -0800296 @Override
Wink Savilled09c4ca2014-11-22 10:08:16 -0800297 public void onSubscriptionsChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800298 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
299 }
300 };
301
Adrian Roos46842d92014-03-27 14:58:03 +0100302 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200303 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Jim Miller9f0753f2015-03-23 23:59:22 -0700304 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200305 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100306
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700307 private static int sCurrentUser;
308
309 public synchronized static void setCurrentUser(int currentUser) {
310 sCurrentUser = currentUser;
311 }
312
313 public synchronized static int getCurrentUser() {
314 return sCurrentUser;
315 }
316
Adrian Roos46842d92014-03-27 14:58:03 +0100317 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700318 public void onTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos46842d92014-03-27 14:58:03 +0100319 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200320 for (int i = 0; i < mCallbacks.size(); i++) {
321 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
322 if (cb != null) {
323 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700324 if (enabled && flags != 0) {
325 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200326 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200327 }
328 }
Adrian Roos46842d92014-03-27 14:58:03 +0100329 }
330
Jim Miller52a61332014-11-12 19:29:51 -0800331 protected void handleSimSubscriptionInfoChanged() {
332 if (DEBUG_SIM_STATES) {
333 Log.v(TAG, "onSubscriptionInfoChanged()");
Wink Savilled09c4ca2014-11-22 10:08:16 -0800334 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
335 if (sil != null) {
336 for (SubscriptionInfo subInfo : sil) {
337 Log.v(TAG, "SubInfo:" + subInfo);
338 }
339 } else {
340 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800341 }
342 }
343 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
344
345 // Hack level over 9000: Because the subscription id is not yet valid when we see the
346 // first update in handleSimStateChange, we need to force refresh all all SIM states
347 // so the subscription id for them is consistent.
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100348 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
Jim Miller52a61332014-11-12 19:29:51 -0800349 for (int i = 0; i < subscriptionInfos.size(); i++) {
350 SubscriptionInfo info = subscriptionInfos.get(i);
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100351 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
352 if (changed) {
353 changedSubscriptions.add(info);
354 }
Jim Miller52a61332014-11-12 19:29:51 -0800355 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100356 for (int i = 0; i < changedSubscriptions.size(); i++) {
357 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800358 for (int j = 0; j < mCallbacks.size(); j++) {
359 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
360 if (cb != null) {
361 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
362 }
363 }
364 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500365 for (int j = 0; j < mCallbacks.size(); j++) {
366 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
367 if (cb != null) {
368 cb.onRefreshCarrierInfo();
369 }
370 }
Jim Miller52a61332014-11-12 19:29:51 -0800371 }
372
Jason Monk052082c2015-06-11 11:35:23 -0400373 private void handleAirplaneModeChanged() {
374 for (int j = 0; j < mCallbacks.size(); j++) {
375 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
376 if (cb != null) {
377 cb.onRefreshCarrierInfo();
378 }
379 }
380 }
381
Wink Savilled09c4ca2014-11-22 10:08:16 -0800382 /** @return List of SubscriptionInfo records, maybe empty but never null */
Adrian Roos316bf542016-08-23 17:53:07 +0200383 public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800384 List<SubscriptionInfo> sil = mSubscriptionInfo;
385 if (sil == null || forceReload) {
386 sil = mSubscriptionManager.getActiveSubscriptionInfoList();
387 }
388 if (sil == null) {
389 // getActiveSubscriptionInfoList was null callers expect an empty list.
390 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
391 } else {
392 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800393 }
394 return mSubscriptionInfo;
395 }
396
Adrian Roos7861c662014-07-25 15:37:28 +0200397 @Override
398 public void onTrustManagedChanged(boolean managed, int userId) {
399 mUserTrustIsManaged.put(userId, managed);
400
401 for (int i = 0; i < mCallbacks.size(); i++) {
402 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
403 if (cb != null) {
404 cb.onTrustManagedChanged(userId);
405 }
406 }
407 }
408
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700409 private void onFingerprintAuthenticated(int userId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700410 Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
Jim Miller9f0753f2015-03-23 23:59:22 -0700411 mUserFingerprintAuthenticated.put(userId, true);
Jorim Jaggi71448a72015-08-18 19:49:04 -0700412
413 // If fingerprint unlocking is allowed, this event will lead to a Keyguard dismiss or to a
414 // wake-up (if Keyguard is not showing), so we don't need to listen until Keyguard is
415 // fully gone.
416 mFingerprintAlreadyAuthenticated = isUnlockingWithFingerprintAllowed();
Jim Millerf41fc962014-06-18 16:33:51 -0700417 for (int i = 0; i < mCallbacks.size(); i++) {
418 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
419 if (cb != null) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700420 cb.onFingerprintAuthenticated(userId);
Jim Millerf41fc962014-06-18 16:33:51 -0700421 }
422 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700423 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700424 }
425
Jim Millerce7eb6d2015-04-03 19:29:13 -0700426 private void handleFingerprintAuthFailed() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700427 for (int i = 0; i < mCallbacks.size(); i++) {
428 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
429 if (cb != null) {
430 cb.onFingerprintAuthFailed();
431 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700432 }
Jim Millerce7eb6d2015-04-03 19:29:13 -0700433 handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized));
434 }
Jim Millerf41fc962014-06-18 16:33:51 -0700435
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700436 private void handleFingerprintAcquired(int acquireInfo) {
437 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
438 return;
439 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700440 for (int i = 0; i < mCallbacks.size(); i++) {
441 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
442 if (cb != null) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700443 cb.onFingerprintAcquired();
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700444 }
445 }
446 }
447
Jim Miller837fa7e2016-08-08 20:16:22 -0700448 private void handleFingerprintAuthenticated(int authUserId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700449 Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
Jim Millerf41fc962014-06-18 16:33:51 -0700450 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700451 final int userId;
452 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800453 userId = ActivityManager.getService().getCurrentUser().id;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700454 } catch (RemoteException e) {
455 Log.e(TAG, "Failed to get current user id: ", e);
456 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700457 }
Jim Miller837fa7e2016-08-08 20:16:22 -0700458 if (userId != authUserId) {
459 Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId);
460 return;
461 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700462 if (isFingerprintDisabled(userId)) {
463 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
464 return;
465 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700466 onFingerprintAuthenticated(userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700467 } finally {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700468 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
Jim Millerf41fc962014-06-18 16:33:51 -0700469 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700470 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700471 }
472
Jim Miller9f0753f2015-03-23 23:59:22 -0700473 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700474 for (int i = 0; i < mCallbacks.size(); i++) {
475 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
476 if (cb != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700477 cb.onFingerprintHelp(msgId, helpString);
478 }
479 }
480 }
481
482 private void handleFingerprintError(int msgId, String errString) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700483 if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
484 && mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
485 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
486 startListeningForFingerprint();
487 } else {
488 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
489 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700490 for (int i = 0; i < mCallbacks.size(); i++) {
491 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
492 if (cb != null) {
493 cb.onFingerprintError(msgId, errString);
Jim Millerf41fc962014-06-18 16:33:51 -0700494 }
495 }
496 }
497
Jorim Jaggi3a464782015-08-28 16:59:13 -0700498 private void handleFingerprintLockoutReset() {
499 updateFingerprintListeningState();
500 }
501
Jorim Jaggi86bed402015-08-20 18:20:02 -0700502 private void setFingerprintRunningState(int fingerprintRunningState) {
503 boolean wasRunning = mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
504 boolean isRunning = fingerprintRunningState == FINGERPRINT_STATE_RUNNING;
505 mFingerprintRunningState = fingerprintRunningState;
506
507 // Clients of KeyguardUpdateMonitor don't care about the internal state about the
508 // asynchronousness of the cancel cycle. So only notify them if the actualy running state
509 // has changed.
510 if (wasRunning != isRunning) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700511 notifyFingerprintRunningStateChanged();
512 }
513 }
514
515 private void notifyFingerprintRunningStateChanged() {
516 for (int i = 0; i < mCallbacks.size(); i++) {
517 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
518 if (cb != null) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700519 cb.onFingerprintRunningStateChanged(isFingerprintDetectionRunning());
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700520 }
521 }
522 }
Adrian Roos4a410172014-08-20 17:41:44 +0200523 private void handleFaceUnlockStateChanged(boolean running, int userId) {
524 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200525 for (int i = 0; i < mCallbacks.size(); i++) {
526 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
527 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200528 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200529 }
530 }
531 }
532
Adrian Roos4a410172014-08-20 17:41:44 +0200533 public boolean isFaceUnlockRunning(int userId) {
534 return mUserFaceUnlockRunning.get(userId);
535 }
536
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700537 public boolean isFingerprintDetectionRunning() {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700538 return mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700539 }
540
Jim Miller50e62182014-04-23 17:25:00 -0700541 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100542 // Don't allow trust agent if device is secured with a SIM PIN. This is here
543 // mainly because there's no other way to prompt the user to enter their SIM PIN
544 // once they get past the keyguard screen.
545 final boolean disabledBySimPin = isSimPinSecure();
546 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700547 }
548
Jim Miller06e34502014-07-17 14:46:05 -0700549 private boolean isFingerprintDisabled(int userId) {
550 final DevicePolicyManager dpm =
551 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
552 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
Adrian Roos733b6632015-08-21 14:32:35 -0700553 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0
554 || isSimPinSecure();
Jim Miller06e34502014-07-17 14:46:05 -0700555 }
556
Selim Cineke8bae622015-07-15 13:24:06 -0700557 public boolean getUserCanSkipBouncer(int userId) {
Selim Cinek1fcafc42015-07-20 14:39:25 -0700558 return getUserHasTrust(userId) || (mUserFingerprintAuthenticated.get(userId)
559 && isUnlockingWithFingerprintAllowed());
Selim Cineke8bae622015-07-15 13:24:06 -0700560 }
561
Adrian Roos46842d92014-03-27 14:58:03 +0100562 public boolean getUserHasTrust(int userId) {
Selim Cineke8bae622015-07-15 13:24:06 -0700563 return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100564 }
565
Adrian Roos7861c662014-07-25 15:37:28 +0200566 public boolean getUserTrustIsManaged(int userId) {
567 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
568 }
569
Selim Cinek1fcafc42015-07-20 14:39:25 -0700570 public boolean isUnlockingWithFingerprintAllowed() {
Michal Karpinskic52f8672016-11-18 11:32:45 +0000571 return mStrongAuthTracker.isUnlockingWithFingerprintAllowed();
Adrian Roosb5e47222015-08-14 15:53:06 -0700572 }
573
Jorim Jaggi031f7952016-09-01 16:39:26 -0700574 public boolean needsSlowUnlockTransition() {
575 return mNeedsSlowUnlockTransition;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700576 }
577
Adrian Roosb5e47222015-08-14 15:53:06 -0700578 public StrongAuthTracker getStrongAuthTracker() {
579 return mStrongAuthTracker;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700580 }
581
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700582 public void reportSuccessfulStrongAuthUnlockAttempt() {
Jim Millere0507bb2015-08-12 20:30:34 -0700583 if (mFpm != null) {
584 byte[] token = null; /* TODO: pass real auth token once fp HAL supports it */
585 mFpm.resetTimeout(token);
586 }
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700587 }
588
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700589 private void notifyStrongAuthStateChanged(int userId) {
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700590 for (int i = 0; i < mCallbacks.size(); i++) {
591 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
592 if (cb != null) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700593 cb.onStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700594 }
595 }
Selim Cinek1fcafc42015-07-20 14:39:25 -0700596 }
597
Adrian Roos91ba3072017-02-14 16:50:46 +0100598 public boolean isScreenOn() {
599 return mScreenOn;
600 }
601
Jim Miller8f09fd22013-03-14 19:04:28 -0700602 static class DisplayClientState {
603 public int clientGeneration;
604 public boolean clearing;
605 public PendingIntent intent;
606 public int playbackState;
607 public long playbackEventTime;
608 }
609
610 private DisplayClientState mDisplayClientState = new DisplayClientState();
611
Jim Millerbbf1a742012-07-17 18:30:30 -0700612 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
613
Jim Millerd72d5ac2015-09-29 18:55:32 -0700614 @Override
Jim Millerbbf1a742012-07-17 18:30:30 -0700615 public void onReceive(Context context, Intent intent) {
616 final String action = intent.getAction();
617 if (DEBUG) Log.d(TAG, "received broadcast " + action);
618
619 if (Intent.ACTION_TIME_TICK.equals(action)
620 || Intent.ACTION_TIME_CHANGED.equals(action)
Adrian Roos48c796c2014-09-01 14:59:23 +0200621 || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700622 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Jim Millerbbf1a742012-07-17 18:30:30 -0700623 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
624 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
625 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
626 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
627 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
Adrian Roos0c859ae2015-11-23 16:47:50 -0800628
629 final int maxChargingMicroAmp = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
630 int maxChargingMicroVolt = intent.getIntExtra(EXTRA_MAX_CHARGING_VOLTAGE, -1);
631 final int maxChargingMicroWatt;
632
633 if (maxChargingMicroVolt <= 0) {
634 maxChargingMicroVolt = DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT;
635 }
636 if (maxChargingMicroAmp > 0) {
637 // Calculating muW = muA * muV / (10^6 mu^2 / mu); splitting up the divisor
638 // to maintain precision equally on both factors.
639 maxChargingMicroWatt = (maxChargingMicroAmp / 1000)
640 * (maxChargingMicroVolt / 1000);
641 } else {
642 maxChargingMicroWatt = -1;
643 }
Jim Millerbbf1a742012-07-17 18:30:30 -0700644 final Message msg = mHandler.obtainMessage(
Adrian Roos7b043112015-07-10 13:00:33 -0700645 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
Adrian Roos0c859ae2015-11-23 16:47:50 -0800646 maxChargingMicroWatt));
Jim Millerbbf1a742012-07-17 18:30:30 -0700647 mHandler.sendMessage(msg);
648 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Jim Miller52a61332014-11-12 19:29:51 -0800649 SimData args = SimData.fromIntent(intent);
Jim Millerbbf1a742012-07-17 18:30:30 -0700650 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -0800651 Log.v(TAG, "action " + action
652 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
653 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -0700654 }
Jim Miller52a61332014-11-12 19:29:51 -0800655 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
656 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -0700657 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
658 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
659 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
660 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
661 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
662 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Jason Monk052082c2015-06-11 11:35:23 -0400663 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
664 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800665 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700666 dispatchBootCompleted();
Etan Cohen47051d82015-07-06 16:19:04 -0700667 } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
668 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
669 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
670 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
671 if (DEBUG) {
672 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
673 + subId);
674 }
675 mHandler.sendMessage(
676 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
Jim Millerbbf1a742012-07-17 18:30:30 -0700677 }
678 }
679 };
Jim Miller2de5ee82012-06-14 22:22:50 -0700680
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700681 private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
682
Jim Millerd72d5ac2015-09-29 18:55:32 -0700683 @Override
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700684 public void onReceive(Context context, Intent intent) {
685 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +0200686 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
687 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
688 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700689 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
690 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +0200691 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700692 Trace.beginSection("KeyguardUpdateMonitor.mBroadcastAllReceiver#onReceive ACTION_FACE_UNLOCK_STARTED");
Adrian Roos48c796c2014-09-01 14:59:23 +0200693 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
694 getSendingUserId()));
Nick Desaulniers1d396752016-07-25 15:05:33 -0700695 Trace.endSection();
Adrian Roos48c796c2014-09-01 14:59:23 +0200696 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
697 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
698 getSendingUserId()));
699 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
700 .equals(action)) {
701 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -0700702 } else if (ACTION_USER_UNLOCKED.equals(action)) {
703 mHandler.sendEmptyMessage(MSG_USER_UNLOCKED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700704 }
705 }
706 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700707
Jorim Jaggi3a464782015-08-28 16:59:13 -0700708 private final FingerprintManager.LockoutResetCallback mLockoutResetCallback
709 = new FingerprintManager.LockoutResetCallback() {
710 @Override
711 public void onLockoutReset() {
712 handleFingerprintLockoutReset();
713 }
714 };
715
Jim Miller9f0753f2015-03-23 23:59:22 -0700716 private FingerprintManager.AuthenticationCallback mAuthenticationCallback
717 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -0700718
719 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -0700720 public void onAuthenticationFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700721 handleFingerprintAuthFailed();
Jim Millerce7eb6d2015-04-03 19:29:13 -0700722 };
723
724 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700725 public void onAuthenticationSucceeded(AuthenticationResult result) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700726 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
Jim Miller837fa7e2016-08-08 20:16:22 -0700727 handleFingerprintAuthenticated(result.getUserId());
Nick Desaulniers1d396752016-07-25 15:05:33 -0700728 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700729 }
730
731 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700732 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700733 handleFingerprintHelp(helpMsgId, helpString.toString());
Jim Miller9f0753f2015-03-23 23:59:22 -0700734 }
735
736 @Override
737 public void onAuthenticationError(int errMsgId, CharSequence errString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700738 handleFingerprintError(errMsgId, errString.toString());
739 }
740
741 @Override
742 public void onAuthenticationAcquired(int acquireInfo) {
743 handleFingerprintAcquired(acquireInfo);
Jim Millerf41fc962014-06-18 16:33:51 -0700744 }
745 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700746 private CancellationSignal mFingerprintCancelSignal;
747 private FingerprintManager mFpm;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700748
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800749 /**
Jim Miller47088bb2009-11-24 00:40:16 -0800750 * When we receive a
751 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -0700752 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800753 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -0800754 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800755 */
Jim Miller52a61332014-11-12 19:29:51 -0800756 private static class SimData {
757 public State simState;
758 public int slotId;
759 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800760
Jim Miller52a61332014-11-12 19:29:51 -0800761 SimData(State state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -0800762 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -0800763 slotId = slot;
764 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -0800765 }
766
Jim Miller52a61332014-11-12 19:29:51 -0800767 static SimData fromIntent(Intent intent) {
768 State state;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800769 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
770 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
771 }
Wink Savillea639b312012-07-10 12:37:54 -0700772 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
Jim Miller52a61332014-11-12 19:29:51 -0800773 int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0);
774 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
Wink Savilled09c4ca2014-11-22 10:08:16 -0800775 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea639b312012-07-10 12:37:54 -0700776 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -0700777 final String absentReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700778 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -0700779
Wink Savillea639b312012-07-10 12:37:54 -0700780 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -0700781 absentReason)) {
Wink Savillea639b312012-07-10 12:37:54 -0700782 state = IccCardConstants.State.PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -0700783 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700784 state = IccCardConstants.State.ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -0700785 }
Wink Savillea639b312012-07-10 12:37:54 -0700786 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
787 state = IccCardConstants.State.READY;
788 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800789 final String lockedReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700790 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
791 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
792 state = IccCardConstants.State.PIN_REQUIRED;
793 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
794 state = IccCardConstants.State.PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800795 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700796 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800797 }
Wink Savillea639b312012-07-10 12:37:54 -0700798 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
799 state = IccCardConstants.State.NETWORK_LOCKED;
Jim Miller109f1fd2012-09-19 20:44:16 -0700800 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
801 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
802 // This is required because telephony doesn't return to "READY" after
803 // these state transitions. See bug 7197471.
804 state = IccCardConstants.State.READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800805 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700806 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800807 }
Jim Miller52a61332014-11-12 19:29:51 -0800808 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800809 }
810
Jim Millerd72d5ac2015-09-29 18:55:32 -0700811 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800812 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -0800813 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800814 }
815 }
816
Adrian Roos12c1ef52014-06-04 13:54:08 +0200817 public static class BatteryStatus {
Adrian Roos7b043112015-07-10 13:00:33 -0700818 public static final int CHARGING_UNKNOWN = -1;
819 public static final int CHARGING_SLOWLY = 0;
820 public static final int CHARGING_REGULAR = 1;
821 public static final int CHARGING_FAST = 2;
822
Jim Miller16464b82011-10-20 21:10:13 -0700823 public final int status;
824 public final int level;
825 public final int plugged;
826 public final int health;
Adrian Roos0c859ae2015-11-23 16:47:50 -0800827 public final int maxChargingWattage;
828 public BatteryStatus(int status, int level, int plugged, int health,
829 int maxChargingWattage) {
Jim Miller16464b82011-10-20 21:10:13 -0700830 this.status = status;
831 this.level = level;
832 this.plugged = plugged;
833 this.health = health;
Adrian Roos0c859ae2015-11-23 16:47:50 -0800834 this.maxChargingWattage = maxChargingWattage;
Jim Miller16464b82011-10-20 21:10:13 -0700835 }
836
Jim Millerbbf1a742012-07-17 18:30:30 -0700837 /**
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700838 * Determine whether the device is plugged in (USB, power, or wireless).
Jim Millerbbf1a742012-07-17 18:30:30 -0700839 * @return true if the device is plugged in.
840 */
Adrian Roosad3bc7f2014-10-30 18:29:38 +0100841 public boolean isPluggedIn() {
Jim Millerbbf1a742012-07-17 18:30:30 -0700842 return plugged == BatteryManager.BATTERY_PLUGGED_AC
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700843 || plugged == BatteryManager.BATTERY_PLUGGED_USB
844 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Jim Millerbbf1a742012-07-17 18:30:30 -0700845 }
846
847 /**
848 * Whether or not the device is charged. Note that some devices never return 100% for
849 * battery level, so this allows either battery level or status to determine if the
850 * battery is charged.
851 * @return true if the device is charged
852 */
853 public boolean isCharged() {
854 return status == BATTERY_STATUS_FULL || level >= 100;
855 }
856
857 /**
858 * Whether battery is low and needs to be charged.
859 * @return true if battery is low
860 */
861 public boolean isBatteryLow() {
862 return level < LOW_BATTERY_THRESHOLD;
863 }
864
Adrian Roos7b043112015-07-10 13:00:33 -0700865 public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
Adrian Roos0c859ae2015-11-23 16:47:50 -0800866 return maxChargingWattage <= 0 ? CHARGING_UNKNOWN :
867 maxChargingWattage < slowThreshold ? CHARGING_SLOWLY :
868 maxChargingWattage > fastThreshold ? CHARGING_FAST :
Adrian Roos7b043112015-07-10 13:00:33 -0700869 CHARGING_REGULAR;
870 }
Jim Miller16464b82011-10-20 21:10:13 -0700871 }
872
Adrian Roosb5e47222015-08-14 15:53:06 -0700873 public class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
Rakesh Iyera7aa4d62016-01-19 17:27:23 -0800874 public StrongAuthTracker(Context context) {
875 super(context);
876 }
Adrian Roosb5e47222015-08-14 15:53:06 -0700877
878 public boolean isUnlockingWithFingerprintAllowed() {
879 int userId = getCurrentUser();
880 return isFingerprintAllowedForUser(userId);
881 }
882
883 public boolean hasUserAuthenticatedSinceBoot() {
884 int userId = getCurrentUser();
885 return (getStrongAuthForUser(userId)
886 & STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
887 }
888
889 @Override
890 public void onStrongAuthRequiredChanged(int userId) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700891 notifyStrongAuthStateChanged(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -0700892 }
893 }
894
Jim Millerdcb3d842012-08-23 19:18:12 -0700895 public static KeyguardUpdateMonitor getInstance(Context context) {
896 if (sInstance == null) {
897 sInstance = new KeyguardUpdateMonitor(context);
898 }
899 return sInstance;
900 }
901
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700902 protected void handleStartedWakingUp() {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700903 Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
Jorim Jaggi864e64b2015-05-20 14:13:23 -0700904 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -0700905 final int count = mCallbacks.size();
906 for (int i = 0; i < count; i++) {
907 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
908 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700909 cb.onStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -0700910 }
911 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700912 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -0700913 }
914
Jorim Jaggi95e40382015-09-16 15:53:42 -0700915 protected void handleStartedGoingToSleep(int arg1) {
Jim Millerf41fc962014-06-18 16:33:51 -0700916 clearFingerprintRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -0700917 final int count = mCallbacks.size();
918 for (int i = 0; i < count; i++) {
919 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
920 if (cb != null) {
Jorim Jaggi95e40382015-09-16 15:53:42 -0700921 cb.onStartedGoingToSleep(arg1);
922 }
923 }
924 mGoingToSleep = true;
925 mFingerprintAlreadyAuthenticated = false;
926 updateFingerprintListeningState();
927 }
928
929 protected void handleFinishedGoingToSleep(int arg1) {
930 mGoingToSleep = false;
931 final int count = mCallbacks.size();
932 for (int i = 0; i < count; i++) {
933 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
934 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700935 cb.onFinishedGoingToSleep(arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700936 }
937 }
Jorim Jaggiea657062015-04-28 13:45:11 -0700938 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -0700939 }
940
Jorim Jaggif1518da2015-07-30 11:56:36 -0700941 private void handleScreenTurnedOn() {
942 final int count = mCallbacks.size();
943 for (int i = 0; i < count; i++) {
944 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
945 if (cb != null) {
946 cb.onScreenTurnedOn();
947 }
948 }
949 }
950
951 private void handleScreenTurnedOff() {
952 final int count = mCallbacks.size();
953 for (int i = 0; i < count; i++) {
954 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
955 if (cb != null) {
956 cb.onScreenTurnedOff();
957 }
958 }
959 }
960
Selim Cinek99415392016-09-09 14:58:41 -0700961 private void handleDreamingStateChanged(int dreamStart) {
962 final int count = mCallbacks.size();
963 boolean showingDream = dreamStart == 1;
964 for (int i = 0; i < count; i++) {
965 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
966 if (cb != null) {
967 cb.onDreamingStateChanged(showingDream);
968 }
969 }
970 }
971
Adam Powell43a372f2013-09-27 17:43:53 -0700972 /**
973 * IMPORTANT: Must be called from UI thread.
974 */
975 public void dispatchSetBackground(Bitmap bmp) {
976 if (DEBUG) Log.d(TAG, "dispatchSetBackground");
977 final int count = mCallbacks.size();
978 for (int i = 0; i < count; i++) {
979 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
980 if (cb != null) {
981 cb.onSetBackground(bmp);
982 }
983 }
984 }
985
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700986 private void handleUserInfoChanged(int userId) {
987 for (int i = 0; i < mCallbacks.size(); i++) {
988 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
989 if (cb != null) {
990 cb.onUserInfoChanged(userId);
991 }
992 }
993 }
994
Jorim Jaggidadafd42016-09-30 07:20:25 -0700995 private void handleUserUnlocked() {
996 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
997 for (int i = 0; i < mCallbacks.size(); i++) {
998 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
999 if (cb != null) {
1000 cb.onUserUnlocked();
1001 }
1002 }
1003 }
1004
Jim Millerdcb3d842012-08-23 19:18:12 -07001005 private KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001006 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -08001007 mSubscriptionManager = SubscriptionManager.from(context);
Michael Jurkafff56142012-11-28 16:51:00 -08001008 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001009 mStrongAuthTracker = new StrongAuthTracker(context);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001010
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001011 // Since device can't be un-provisioned, we only need to register a content observer
1012 // to update mDeviceProvisioned when we are...
1013 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001014 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001015 }
Jim Miller47088bb2009-11-24 00:40:16 -08001016
Jim Millerbbf1a742012-07-17 18:30:30 -07001017 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Adrian Roos7b043112015-07-10 13:00:33 -07001018 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001019
Jim Millerbbf1a742012-07-17 18:30:30 -07001020 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001021 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001022 filter.addAction(Intent.ACTION_TIME_TICK);
1023 filter.addAction(Intent.ACTION_TIME_CHANGED);
1024 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
1025 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Jason Monk052082c2015-06-11 11:35:23 -04001026 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001027 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Etan Cohen47051d82015-07-06 16:19:04 -07001028 filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -08001029 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -08001030 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Jim Millerbbf1a742012-07-17 18:30:30 -07001031 context.registerReceiver(mBroadcastReceiver, filter);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001032
Adam Cohenc276e822012-11-08 13:01:08 -08001033 final IntentFilter bootCompleteFilter = new IntentFilter();
1034 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1035 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
1036 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter);
1037
Adrian Roos48c796c2014-09-01 14:59:23 +02001038 final IntentFilter allUserFilter = new IntentFilter();
1039 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
1040 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
1041 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
1042 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
1043 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001044 allUserFilter.addAction(ACTION_USER_UNLOCKED);
Adrian Roos48c796c2014-09-01 14:59:23 +02001045 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001046 null, null);
1047
Wink Saville071743f2015-01-12 17:11:04 -08001048 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001049 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001050 ActivityManager.getService().registerUserSwitchObserver(
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001051 new UserSwitchObserver() {
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001052 @Override
1053 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001054 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001055 newUserId, 0, reply));
1056 }
1057 @Override
1058 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001059 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +02001060 newUserId, 0));
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001061 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001062 }, TAG);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001063 } catch (RemoteException e) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001064 e.rethrowAsRuntimeException();
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001065 }
Adrian Roos46842d92014-03-27 14:58:03 +01001066
Jorim Jaggi237b0612015-05-01 14:28:49 -07001067 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
1068 mTrustManager.registerTrustListener(this);
Michal Karpinskic52f8672016-11-18 11:32:45 +00001069 mLockPatternUtils = new LockPatternUtils(context);
1070 mLockPatternUtils.registerStrongAuthTracker(mStrongAuthTracker);
Jim Millerf41fc962014-06-18 16:33:51 -07001071
Jorim Jaggi3f124262016-11-22 13:45:17 +01001072 if (mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_FINGERPRINT)) {
1073 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
1074 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001075 updateFingerprintListeningState();
Jorim Jaggi3a464782015-08-28 16:59:13 -07001076 if (mFpm != null) {
1077 mFpm.addLockoutResetCallback(mLockoutResetCallback);
1078 }
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001079
1080 mUserManager = context.getSystemService(UserManager.class);
Jorim Jaggiea657062015-04-28 13:45:11 -07001081 }
1082
1083 private void updateFingerprintListeningState() {
1084 boolean shouldListenForFingerprint = shouldListenForFingerprint();
Jorim Jaggi86bed402015-08-20 18:20:02 -07001085 if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING && !shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001086 stopListeningForFingerprint();
Jorim Jaggi86bed402015-08-20 18:20:02 -07001087 } else if (mFingerprintRunningState != FINGERPRINT_STATE_RUNNING
1088 && shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001089 startListeningForFingerprint();
1090 }
1091 }
1092
1093 private boolean shouldListenForFingerprint() {
Jorim Jaggi95e40382015-09-16 15:53:42 -07001094 return (mKeyguardIsVisible || !mDeviceInteractive || mBouncer || mGoingToSleep)
1095 && !mSwitchingUser && !mFingerprintAlreadyAuthenticated
1096 && !isFingerprintDisabled(getCurrentUser());
Jim Miller9f0753f2015-03-23 23:59:22 -07001097 }
1098
Jim Millerce7eb6d2015-04-03 19:29:13 -07001099 private void startListeningForFingerprint() {
Jorim Jaggi86bed402015-08-20 18:20:02 -07001100 if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING) {
1101 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING_RESTARTING);
1102 return;
1103 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001104 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -07001105 int userId = ActivityManager.getCurrentUser();
Jorim Jaggi71448a72015-08-18 19:49:04 -07001106 if (isUnlockWithFingerprintPossible(userId)) {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001107 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001108 mFingerprintCancelSignal.cancel();
1109 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001110 mFingerprintCancelSignal = new CancellationSignal();
Jim Millerf501b582015-06-03 16:36:31 -07001111 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null, userId);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001112 setFingerprintRunningState(FINGERPRINT_STATE_RUNNING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001113 }
1114 }
1115
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001116 public boolean isUnlockWithFingerprintPossible(int userId) {
Selim Cinek3122fa82015-06-18 01:38:59 -07001117 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
1118 && mFpm.getEnrolledFingerprints(userId).size() > 0;
1119 }
1120
Jorim Jaggiea657062015-04-28 13:45:11 -07001121 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001122 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
Jorim Jaggi86bed402015-08-20 18:20:02 -07001123 if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001124 mFingerprintCancelSignal.cancel();
Jim Millerce7eb6d2015-04-03 19:29:13 -07001125 mFingerprintCancelSignal = null;
Jorim Jaggi86bed402015-08-20 18:20:02 -07001126 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001127 }
Jorim Jaggi86bed402015-08-20 18:20:02 -07001128 if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
1129 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
1130 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001131 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001132
Michael Jurkafff56142012-11-28 16:51:00 -08001133 private boolean isDeviceProvisionedInSettingsDb() {
1134 return Settings.Global.getInt(mContext.getContentResolver(),
1135 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1136 }
1137
Jim Millerbbf1a742012-07-17 18:30:30 -07001138 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -08001139 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001140 @Override
1141 public void onChange(boolean selfChange) {
1142 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -08001143 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001144 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001145 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001146 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001147 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001148 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001149 };
1150
1151 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -07001152 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -08001153 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -07001154
1155 // prevent a race condition between where we check the flag and where we register the
1156 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -08001157 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001158 if (provisioned != mDeviceProvisioned) {
1159 mDeviceProvisioned = provisioned;
1160 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001161 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001162 }
1163 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001164 }
1165
Jim Millerbbf1a742012-07-17 18:30:30 -07001166 /**
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001167 * Update the state whether Keyguard currently has a lockscreen wallpaper.
1168 *
1169 * @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper.
1170 */
1171 public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) {
1172 if (hasLockscreenWallpaper != mHasLockscreenWallpaper) {
1173 mHasLockscreenWallpaper = hasLockscreenWallpaper;
1174 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1175 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1176 if (cb != null) {
1177 cb.onHasLockscreenWallpaperChanged(hasLockscreenWallpaper);
1178 }
1179 }
1180 }
1181 }
1182
1183 /**
1184 * @return Whether Keyguard has a lockscreen wallpaper.
1185 */
1186 public boolean hasLockscreenWallpaper() {
1187 return mHasLockscreenWallpaper;
1188 }
1189
1190 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001191 * Handle {@link #MSG_DPM_STATE_CHANGED}
1192 */
Jim Millerb0304762012-03-13 20:01:25 -07001193 protected void handleDevicePolicyManagerStateChanged() {
Adrian Roos733b6632015-08-21 14:32:35 -07001194 updateFingerprintListeningState();
Jim Millerdcb3d842012-08-23 19:18:12 -07001195 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1196 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1197 if (cb != null) {
1198 cb.onDevicePolicyManagerStateChanged();
1199 }
Jim Millerb0304762012-03-13 20:01:25 -07001200 }
1201 }
1202
Jim Millerbbf1a742012-07-17 18:30:30 -07001203 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001204 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -07001205 */
Chris Wrenf41c61b2012-11-29 15:19:54 -05001206 protected void handleUserSwitching(int userId, IRemoteCallback reply) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001207 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001208 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1209 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001210 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -07001211 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001212 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001213 try {
1214 reply.sendResult(null);
1215 } catch (RemoteException e) {
1216 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001217 }
1218
Jim Millerbbf1a742012-07-17 18:30:30 -07001219 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001220 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
1221 */
1222 protected void handleUserSwitchComplete(int userId) {
1223 for (int i = 0; i < mCallbacks.size(); i++) {
1224 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1225 if (cb != null) {
1226 cb.onUserSwitchComplete(userId);
1227 }
1228 }
1229 }
1230
1231 /**
Jim Miller90873d52013-09-26 18:11:38 -07001232 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
1233 * keyguard crashes sometime after boot, then it will never receive this
1234 * broadcast and hence not handle the event. This method is ultimately called by
1235 * PhoneWindowManager in this case.
1236 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001237 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001238 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -07001239 }
1240
1241 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001242 * Handle {@link #MSG_BOOT_COMPLETED}
1243 */
1244 protected void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001245 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001246 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001247 for (int i = 0; i < mCallbacks.size(); i++) {
1248 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1249 if (cb != null) {
1250 cb.onBootCompleted();
1251 }
1252 }
1253 }
1254
1255 /**
Jim Miller5ecd8112013-01-09 18:50:26 -08001256 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001257 * destroyed.
1258 */
1259 public boolean hasBootCompleted() {
1260 return mBootCompleted;
1261 }
1262
1263 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001264 * Handle {@link #MSG_DEVICE_PROVISIONED}
1265 */
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001266 protected void handleDeviceProvisioned() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001267 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001268 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1269 if (cb != null) {
1270 cb.onDeviceProvisioned();
1271 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001272 }
Michael Jurkafff56142012-11-28 16:51:00 -08001273 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001274 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -08001275 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
1276 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001277 }
1278 }
1279
Jim Millerbbf1a742012-07-17 18:30:30 -07001280 /**
1281 * Handle {@link #MSG_PHONE_STATE_CHANGED}
1282 */
Jim Millerc23024d2010-02-24 15:37:00 -08001283 protected void handlePhoneStateChanged(String newState) {
1284 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001285 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
1286 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
1287 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
1288 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
1289 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
1290 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
1291 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001292 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001293 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1294 if (cb != null) {
1295 cb.onPhoneStateChanged(mPhoneState);
1296 }
Jim Millerc23024d2010-02-24 15:37:00 -08001297 }
1298 }
1299
Jim Millerbbf1a742012-07-17 18:30:30 -07001300 /**
1301 * Handle {@link #MSG_RINGER_MODE_CHANGED}
1302 */
Jim Miller47088bb2009-11-24 00:40:16 -08001303 protected void handleRingerModeChange(int mode) {
1304 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001305 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -07001306 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001307 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1308 if (cb != null) {
1309 cb.onRingerModeChanged(mode);
1310 }
Jim Miller47088bb2009-11-24 00:40:16 -08001311 }
1312 }
1313
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001314 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001315 * Handle {@link #MSG_TIME_UPDATE}
1316 */
1317 private void handleTimeUpdate() {
1318 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001319 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001320 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1321 if (cb != null) {
1322 cb.onTimeChanged();
1323 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001324 }
1325 }
1326
1327 /**
1328 * Handle {@link #MSG_BATTERY_UPDATE}
1329 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001330 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001331 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001332 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
1333 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07001334 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001335 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001336 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1337 if (cb != null) {
1338 cb.onRefreshBatteryInfo(status);
1339 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001340 }
1341 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001342 }
1343
1344 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001345 * Handle {@link #MSG_SIM_STATE_CHANGE}
1346 */
Jim Miller52a61332014-11-12 19:29:51 -08001347 private void handleSimStateChange(int subId, int slotId, State state) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001348
Jim Miller52a61332014-11-12 19:29:51 -08001349 if (DEBUG_SIM_STATES) {
1350 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
1351 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001352 }
1353
Wink Savillea54bf652014-12-11 13:37:50 -08001354 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08001355 Log.w(TAG, "invalid subId in handleSimStateChange()");
1356 return;
1357 }
1358
1359 SimData data = mSimDatas.get(subId);
1360 final boolean changed;
1361 if (data == null) {
1362 data = new SimData(state, slotId, subId);
1363 mSimDatas.put(subId, data);
1364 changed = true; // no data yet; force update
1365 } else {
1366 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
1367 data.simState = state;
1368 data.subId = subId;
1369 data.slotId = slotId;
1370 }
1371 if (changed && state != State.UNKNOWN) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001372 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001373 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1374 if (cb != null) {
Jim Miller52a61332014-11-12 19:29:51 -08001375 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07001376 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001377 }
1378 }
1379 }
1380
Jim Millerbbf1a742012-07-17 18:30:30 -07001381 /**
Etan Cohen47051d82015-07-06 16:19:04 -07001382 * Handle {@link #MSG_SERVICE_STATE_CHANGE}
1383 */
1384 private void handleServiceStateChange(int subId, ServiceState serviceState) {
1385 if (DEBUG) {
1386 Log.d(TAG,
1387 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
1388 }
1389
1390 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1391 Log.w(TAG, "invalid subId in handleServiceStateChange()");
1392 return;
1393 }
1394
1395 mServiceStates.put(subId, serviceState);
1396
1397 for (int j = 0; j < mCallbacks.size(); j++) {
1398 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
1399 if (cb != null) {
1400 cb.onRefreshCarrierInfo();
1401 }
1402 }
1403 }
1404
1405 /**
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001406 * Notifies that the visibility state of Keyguard has changed.
1407 *
1408 * <p>Needs to be called from the main thread.
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001409 */
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001410 public void onKeyguardVisibilityChanged(boolean showing) {
1411 if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
1412 mKeyguardIsVisible = showing;
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001413 for (int i = 0; i < mCallbacks.size(); i++) {
1414 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1415 if (cb != null) {
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001416 cb.onKeyguardVisibilityChangedRaw(showing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001417 }
1418 }
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001419 if (!showing) {
Jorim Jaggi71448a72015-08-18 19:49:04 -07001420 mFingerprintAlreadyAuthenticated = false;
1421 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001422 updateFingerprintListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001423 }
1424
Brian Colonna7fce3802013-09-17 15:51:32 -04001425 /**
Selim Cinek1fcafc42015-07-20 14:39:25 -07001426 * Handle {@link #MSG_KEYGUARD_RESET}
1427 */
1428 private void handleKeyguardReset() {
1429 if (DEBUG) Log.d(TAG, "handleKeyguardReset");
Adrian Roosf6d51ac2015-09-02 13:26:25 -07001430 updateFingerprintListeningState();
Jorim Jaggi031f7952016-09-01 16:39:26 -07001431 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1432 }
1433
1434 private boolean resolveNeedsSlowUnlockTransition() {
1435 if (mUserManager.isUserUnlocked(getCurrentUser())) {
1436 return false;
1437 }
1438 Intent homeIntent = new Intent(Intent.ACTION_MAIN)
1439 .addCategory(Intent.CATEGORY_HOME);
1440 ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(homeIntent,
1441 0 /* flags */);
1442 return FALLBACK_HOME_COMPONENT.equals(resolveInfo.getComponentInfo().getComponentName());
Selim Cinek1fcafc42015-07-20 14:39:25 -07001443 }
1444
1445 /**
Adrian Roosb6011622014-05-14 15:52:53 +02001446 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
1447 * @see #sendKeyguardBouncerChanged(boolean)
1448 */
1449 private void handleKeyguardBouncerChanged(int bouncer) {
1450 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
1451 boolean isBouncer = (bouncer == 1);
1452 mBouncer = isBouncer;
1453 for (int i = 0; i < mCallbacks.size(); i++) {
1454 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1455 if (cb != null) {
1456 cb.onKeyguardBouncerChanged(isBouncer);
1457 }
1458 }
Jorim Jaggi3cf7eef2015-09-10 14:36:19 -07001459 updateFingerprintListeningState();
Adrian Roosb6011622014-05-14 15:52:53 +02001460 }
1461
1462 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04001463 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
1464 */
1465 private void handleReportEmergencyCallAction() {
1466 for (int i = 0; i < mCallbacks.size(); i++) {
1467 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1468 if (cb != null) {
1469 cb.onEmergencyCallAction();
1470 }
1471 }
1472 }
1473
Jim Miller16464b82011-10-20 21:10:13 -07001474 private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001475 final boolean nowPluggedIn = current.isPluggedIn();
1476 final boolean wasPluggedIn = old.isPluggedIn();
Jim Miller79a444a2011-02-15 15:02:11 -08001477 final boolean stateChangedWhilePluggedIn =
Jim Miller16464b82011-10-20 21:10:13 -07001478 wasPluggedIn == true && nowPluggedIn == true
1479 && (old.status != current.status);
1480
1481 // change in plug state is always interesting
1482 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001483 return true;
1484 }
1485
1486 // change in battery level while plugged in
Jim Miller16464b82011-10-20 21:10:13 -07001487 if (nowPluggedIn && old.level != current.level) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001488 return true;
1489 }
1490
Jim Miller16464b82011-10-20 21:10:13 -07001491 // change where battery needs charging
Jim Millerbbf1a742012-07-17 18:30:30 -07001492 if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
Jim Miller16464b82011-10-20 21:10:13 -07001493 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001494 }
Adrian Roos76dc5a52015-07-21 16:20:36 -07001495
1496 // change in charging current while plugged in
Adrian Roos0c859ae2015-11-23 16:47:50 -08001497 if (nowPluggedIn && current.maxChargingWattage != old.maxChargingWattage) {
Adrian Roos76dc5a52015-07-21 16:20:36 -07001498 return true;
1499 }
1500
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001501 return false;
1502 }
1503
1504 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001505 * Remove the given observer's callback.
1506 *
Jim Miller6212cc02012-09-05 17:35:31 -07001507 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001508 */
Jim Miller6212cc02012-09-05 17:35:31 -07001509 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
1510 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
1511 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1512 if (mCallbacks.get(i).get() == callback) {
1513 mCallbacks.remove(i);
1514 }
1515 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001516 }
1517
1518 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001519 * Register to receive notifications about general keyguard information
1520 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07001521 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001522 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001523 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Jim Miller6212cc02012-09-05 17:35:31 -07001524 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
1525 // Prevent adding duplicate callbacks
1526 for (int i = 0; i < mCallbacks.size(); i++) {
1527 if (mCallbacks.get(i).get() == callback) {
1528 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
1529 new Exception("Called by"));
1530 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07001531 }
1532 }
Jim Miller6212cc02012-09-05 17:35:31 -07001533 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
1534 removeCallback(null); // remove unused references
1535 sendUpdates(callback);
1536 }
1537
Evan Rosky18396452016-07-27 15:19:37 -07001538 public boolean isSwitchingUser() {
1539 return mSwitchingUser;
1540 }
1541
1542 public void setSwitchingUser(boolean switching) {
1543 mSwitchingUser = switching;
1544 updateFingerprintListeningState();
1545 }
1546
Jim Miller6212cc02012-09-05 17:35:31 -07001547 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
1548 // Notify listener of the current state
1549 callback.onRefreshBatteryInfo(mBatteryStatus);
1550 callback.onTimeChanged();
1551 callback.onRingerModeChanged(mRingMode);
1552 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05001553 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07001554 callback.onClockVisibilityChanged();
Jim Miller52a61332014-11-12 19:29:51 -08001555 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
1556 final SimData state = data.getValue();
1557 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
1558 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001559 }
1560
Selim Cinek1fcafc42015-07-20 14:39:25 -07001561 public void sendKeyguardReset() {
1562 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
1563 }
1564
Adrian Roosb6011622014-05-14 15:52:53 +02001565 /**
1566 * @see #handleKeyguardBouncerChanged(int)
1567 */
1568 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
1569 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
1570 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
1571 message.arg1 = showingBouncer ? 1 : 0;
1572 message.sendToTarget();
1573 }
1574
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001575 /**
Jim Miller90d5d462011-11-17 16:57:01 -08001576 * 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 -08001577 * have the information earlier than waiting for the intent
1578 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08001579 *
1580 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
1581 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001582 */
Jim Miller52a61332014-11-12 19:29:51 -08001583 public void reportSimUnlocked(int subId) {
1584 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
Sanket Padawe7e460252017-03-10 16:18:20 -08001585 int slotId = SubscriptionManager.getSlotIndex(subId);
Jim Miller52a61332014-11-12 19:29:51 -08001586 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001587 }
1588
Brian Colonna7fce3802013-09-17 15:51:32 -04001589 /**
1590 * Report that the emergency call button has been pressed and the emergency dialer is
1591 * about to be displayed.
1592 *
1593 * @param bypassHandler runs immediately.
1594 *
1595 * NOTE: Must be called from UI thread if bypassHandler == true.
1596 */
1597 public void reportEmergencyCallAction(boolean bypassHandler) {
1598 if (!bypassHandler) {
1599 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
1600 } else {
1601 handleReportEmergencyCallAction();
1602 }
1603 }
1604
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001605 /**
1606 * @return Whether the device is provisioned (whether they have gone through
1607 * the setup wizard)
1608 */
1609 public boolean isDeviceProvisioned() {
1610 return mDeviceProvisioned;
1611 }
1612
Jorim Jaggi9f743032015-05-04 15:22:40 -07001613 public void clearFailedUnlockAttempts() {
1614 mFailedAttempts.delete(sCurrentUser);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001615 }
1616
Xiyuan Xiace64cea2016-01-06 08:51:16 -08001617 public int getFailedUnlockAttempts(int userId) {
1618 return mFailedAttempts.get(userId, 0);
Jorim Jaggi9f743032015-05-04 15:22:40 -07001619 }
1620
Xiyuan Xiace64cea2016-01-06 08:51:16 -08001621 public void reportFailedStrongAuthUnlockAttempt(int userId) {
1622 mFailedAttempts.put(userId, getFailedUnlockAttempts(userId) + 1);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001623 }
1624
Jim Millerf41fc962014-06-18 16:33:51 -07001625 public void clearFingerprintRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07001626 mUserFingerprintAuthenticated.clear();
Jim Millerf41fc962014-06-18 16:33:51 -07001627 }
1628
Jim Miller52a61332014-11-12 19:29:51 -08001629 public boolean isSimPinVoiceSecure() {
1630 // TODO: only count SIMs that handle voice
1631 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07001632 }
1633
1634 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08001635 // True if any SIM is pin secure
1636 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
1637 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
1638 }
1639 return false;
1640 }
1641
Jason Monk9ff69bd2014-12-02 16:43:17 -05001642 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08001643 if (mSimDatas.containsKey(subId)) {
1644 return mSimDatas.get(subId).simState;
1645 } else {
1646 return State.UNKNOWN;
1647 }
1648 }
1649
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001650 /**
1651 * @return true if and only if the state has changed for the specified {@code slotId}
1652 */
1653 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08001654
1655 // This is awful. It exists because there are two APIs for getting the SIM status
1656 // that don't return the complete set of values and have different types. In Keyguard we
1657 // need IccCardConstants, but TelephonyManager would only give us
1658 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08001659 final TelephonyManager tele = TelephonyManager.from(mContext);
1660 int simState = tele.getSimState(slotId);
Jim Miller52a61332014-11-12 19:29:51 -08001661 State state;
1662 try {
xinhe18b9c3c2014-12-02 15:03:20 -08001663 state = State.intToState(simState);
Jim Miller52a61332014-11-12 19:29:51 -08001664 } catch(IllegalArgumentException ex) {
xinhe18b9c3c2014-12-02 15:03:20 -08001665 Log.w(TAG, "Unknown sim state: " + simState);
Jim Miller52a61332014-11-12 19:29:51 -08001666 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05001667 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001668 SimData data = mSimDatas.get(subId);
1669 final boolean changed;
1670 if (data == null) {
1671 data = new SimData(state, slotId, subId);
1672 mSimDatas.put(subId, data);
1673 changed = true; // no data yet; force update
1674 } else {
1675 changed = data.simState != state;
1676 data.simState = state;
1677 }
1678 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07001679 }
1680
1681 public static boolean isSimPinSecure(IccCardConstants.State state) {
1682 final IccCardConstants.State simState = state;
1683 return (simState == IccCardConstants.State.PIN_REQUIRED
1684 || simState == IccCardConstants.State.PUK_REQUIRED
1685 || simState == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07001686 }
Jim Miller8f09fd22013-03-14 19:04:28 -07001687
1688 public DisplayClientState getCachedDisplayClientState() {
1689 return mDisplayClientState;
1690 }
Jim Miller20daffd2013-10-07 14:59:53 -07001691
1692 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
1693 // (KeyguardViewMediator, KeyguardHostView)
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001694 public void dispatchStartedWakingUp() {
1695 synchronized (this) {
1696 mDeviceInteractive = true;
1697 }
1698 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
1699 }
1700
Jorim Jaggi95e40382015-09-16 15:53:42 -07001701 public void dispatchStartedGoingToSleep(int why) {
1702 mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
1703 }
1704
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001705 public void dispatchFinishedGoingToSleep(int why) {
1706 synchronized(this) {
1707 mDeviceInteractive = false;
1708 }
1709 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
1710 }
1711
Jim Miller20daffd2013-10-07 14:59:53 -07001712 public void dispatchScreenTurnedOn() {
1713 synchronized (this) {
1714 mScreenOn = true;
1715 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001716 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
Jim Miller20daffd2013-10-07 14:59:53 -07001717 }
1718
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001719 public void dispatchScreenTurnedOff() {
Jim Miller20daffd2013-10-07 14:59:53 -07001720 synchronized(this) {
1721 mScreenOn = false;
1722 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001723 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
Jim Miller20daffd2013-10-07 14:59:53 -07001724 }
1725
Selim Cinek99415392016-09-09 14:58:41 -07001726 public void dispatchDreamingStarted() {
1727 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 1, 0));
1728 }
1729
1730 public void dispatchDreamingStopped() {
1731 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 0, 0));
1732 }
1733
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001734 public boolean isDeviceInteractive() {
1735 return mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -07001736 }
Jim Miller52a61332014-11-12 19:29:51 -08001737
Jorim Jaggi95e40382015-09-16 15:53:42 -07001738 public boolean isGoingToSleep() {
1739 return mGoingToSleep;
1740 }
1741
Jim Miller52a61332014-11-12 19:29:51 -08001742 /**
1743 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
1744 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08001745 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08001746 */
1747 public int getNextSubIdForState(State state) {
1748 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08001749 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08001750 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
1751 for (int i = 0; i < list.size(); i++) {
1752 final SubscriptionInfo info = list.get(i);
1753 final int id = info.getSubscriptionId();
Sanket Padawe7e460252017-03-10 16:18:20 -08001754 int slotId = SubscriptionManager.getSlotIndex(id);
Jim Miller52a61332014-11-12 19:29:51 -08001755 if (state == getSimState(id) && bestSlotId > slotId ) {
1756 resultId = id;
1757 bestSlotId = slotId;
1758 }
1759 }
1760 return resultId;
1761 }
1762
1763 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
1764 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
1765 for (int i = 0; i < list.size(); i++) {
1766 SubscriptionInfo info = list.get(i);
1767 if (subId == info.getSubscriptionId()) return info;
1768 }
1769 return null; // not found
1770 }
Jason Monkab525272015-07-13 17:02:49 -04001771
1772 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1773 pw.println("KeyguardUpdateMonitor state:");
1774 pw.println(" SIM States:");
1775 for (SimData data : mSimDatas.values()) {
1776 pw.println(" " + data.toString());
1777 }
1778 pw.println(" Subs:");
1779 if (mSubscriptionInfo != null) {
1780 for (int i = 0; i < mSubscriptionInfo.size(); i++) {
1781 pw.println(" " + mSubscriptionInfo.get(i));
1782 }
1783 }
1784 pw.println(" Service states:");
1785 for (int subId : mServiceStates.keySet()) {
1786 pw.println(" " + subId + "=" + mServiceStates.get(subId));
1787 }
Jim Millerd72d5ac2015-09-29 18:55:32 -07001788 if (mFpm != null && mFpm.isHardwareDetected()) {
1789 final int userId = ActivityManager.getCurrentUser();
1790 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
1791 pw.println(" Fingerprint state (user=" + userId + ")");
1792 pw.println(" allowed=" + isUnlockingWithFingerprintAllowed());
1793 pw.println(" auth'd=" + mUserFingerprintAuthenticated.get(userId));
1794 pw.println(" authSinceBoot="
1795 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
1796 pw.println(" disabled(DPM)=" + isFingerprintDisabled(userId));
1797 pw.println(" possible=" + isUnlockWithFingerprintPossible(userId));
1798 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
Jim Millerd72d5ac2015-09-29 18:55:32 -07001799 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
1800 }
Jason Monkab525272015-07-13 17:02:49 -04001801 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001802}