blob: 57ee319f8ff354ce0aab381393cf39718ecc7d19 [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 Jaggiccdfa932015-04-13 16:29:48 -070019import android.app.ActivityManager;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070020import android.app.ActivityManagerNative;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020021import android.app.AlarmManager;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070022import android.app.IUserSwitchObserver;
Jim Miller8f09fd22013-03-14 19:04:28 -070023import android.app.PendingIntent;
Jim Millerb0304762012-03-13 20:01:25 -070024import android.app.admin.DevicePolicyManager;
Adrian Roos46842d92014-03-27 14:58:03 +010025import android.app.trust.TrustManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080026import android.content.BroadcastReceiver;
27import android.content.Context;
28import android.content.Intent;
29import android.content.IntentFilter;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080030import android.database.ContentObserver;
Jim Miller8f09fd22013-03-14 19:04:28 -070031import android.graphics.Bitmap;
Jorim Jaggi3a464782015-08-28 16:59:13 -070032import android.hardware.fingerprint.Fingerprint;
Jorim Jaggi86bed402015-08-20 18:20:02 -070033import android.hardware.fingerprint.FingerprintManager;
34import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
35import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
Jim Miller47088bb2009-11-24 00:40:16 -080036import android.media.AudioManager;
Jim Miller79a444a2011-02-15 15:02:11 -080037import android.os.BatteryManager;
Jim Miller9f0753f2015-03-23 23:59:22 -070038import android.os.CancellationSignal;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080039import android.os.Handler;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070040import android.os.IRemoteCallback;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080041import android.os.Message;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070042import android.os.RemoteException;
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -070043import android.os.SystemClock;
Amith Yamasanie8e93a12013-05-09 18:12:30 -070044import android.os.UserHandle;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080045import android.provider.Settings;
Etan Cohen47051d82015-07-06 16:19:04 -070046import android.telephony.ServiceState;
Jim Miller52a61332014-11-12 19:29:51 -080047import android.telephony.SubscriptionInfo;
Jim Miller52a61332014-11-12 19:29:51 -080048import android.telephony.SubscriptionManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -080049import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Jim Millerc23024d2010-02-24 15:37:00 -080050import android.telephony.TelephonyManager;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -070051import android.util.ArraySet;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080052import android.util.Log;
Adrian Roos46842d92014-03-27 14:58:03 +010053import android.util.SparseBooleanArray;
Jorim Jaggi9f743032015-05-04 15:22:40 -070054import android.util.SparseIntArray;
Adrian Roos46842d92014-03-27 14:58:03 +010055
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080056import com.google.android.collect.Lists;
57
Jorim Jaggi86bed402015-08-20 18:20:02 -070058import com.android.internal.telephony.IccCardConstants;
59import com.android.internal.telephony.IccCardConstants.State;
60import com.android.internal.telephony.PhoneConstants;
61import com.android.internal.telephony.TelephonyIntents;
Adrian Roosb5e47222015-08-14 15:53:06 -070062import com.android.internal.widget.LockPatternUtils;
Jorim Jaggi86bed402015-08-20 18:20:02 -070063
Jason Monkab525272015-07-13 17:02:49 -040064import java.io.FileDescriptor;
65import java.io.PrintWriter;
Jim Millerdcb3d842012-08-23 19:18:12 -070066import java.lang.ref.WeakReference;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080067import java.util.ArrayList;
Jim Miller52a61332014-11-12 19:29:51 -080068import java.util.HashMap;
69import java.util.List;
70import java.util.Map.Entry;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080071
Jorim Jaggi86bed402015-08-20 18:20:02 -070072import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
73import static android.os.BatteryManager.BATTERY_STATUS_FULL;
74import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
75import static android.os.BatteryManager.EXTRA_HEALTH;
76import static android.os.BatteryManager.EXTRA_LEVEL;
77import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
78import static android.os.BatteryManager.EXTRA_PLUGGED;
79import static android.os.BatteryManager.EXTRA_STATUS;
80
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080081/**
82 * Watches for updates that may be interesting to the keyguard, and provides
83 * the up to date information as well as a registration for callbacks that care
84 * to be updated.
85 *
86 * Note: under time crunch, this has been extended to include some stuff that
87 * doesn't really belong here. see {@link #handleBatteryUpdate} where it shutdowns
Jim Miller258341c2012-08-30 16:50:10 -070088 * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()}
89 * and {@link #clearFailedUnlockAttempts()}. Maybe we should rename this 'KeyguardContext'...
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080090 */
Adrian Roos46842d92014-03-27 14:58:03 +010091public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080092
Jim Millerbbf1a742012-07-17 18:30:30 -070093 private static final String TAG = "KeyguardUpdateMonitor";
Jorim Jaggi5cf17872014-03-26 18:31:48 +010094 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller52a61332014-11-12 19:29:51 -080095 private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
Jim Millerbbf1a742012-07-17 18:30:30 -070096 private static final int LOW_BATTERY_THRESHOLD = 20;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080097
Jorim Jaggie7b12522014-08-06 16:41:21 +020098 private static final String ACTION_FACE_UNLOCK_STARTED
99 = "com.android.facelock.FACE_UNLOCK_STARTED";
100 private static final String ACTION_FACE_UNLOCK_STOPPED
101 = "com.android.facelock.FACE_UNLOCK_STOPPED";
102
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700103 private static final String ACTION_STRONG_AUTH_TIMEOUT =
104 "com.android.systemui.ACTION_STRONG_AUTH_TIMEOUT";
105 private static final String USER_ID = "com.android.systemui.USER_ID";
106
107 private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
108
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700109 /**
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700110 * Milliseconds after unlocking with fingerprint times out, i.e. the user has to use a
111 * strong auth method like password, PIN or pattern.
112 */
113 private static final long FINGERPRINT_UNLOCK_TIMEOUT_MS = 72 * 60 * 60 * 1000;
114
Jim Millerbbf1a742012-07-17 18:30:30 -0700115 // Callback messages
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800116 private static final int MSG_TIME_UPDATE = 301;
117 private static final int MSG_BATTERY_UPDATE = 302;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800118 private static final int MSG_SIM_STATE_CHANGE = 304;
Jim Miller47088bb2009-11-24 00:40:16 -0800119 private static final int MSG_RINGER_MODE_CHANGED = 305;
Jim Millerc23024d2010-02-24 15:37:00 -0800120 private static final int MSG_PHONE_STATE_CHANGED = 306;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700121 private static final int MSG_DEVICE_PROVISIONED = 308;
Jim Miller57375342012-09-09 15:20:31 -0700122 private static final int MSG_DPM_STATE_CHANGED = 309;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500123 private static final int MSG_USER_SWITCHING = 310;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700124 private static final int MSG_KEYGUARD_RESET = 312;
Jim Millerf41fc962014-06-18 16:33:51 -0700125 private static final int MSG_BOOT_COMPLETED = 313;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500126 private static final int MSG_USER_SWITCH_COMPLETE = 314;
Jim Millerf41fc962014-06-18 16:33:51 -0700127 private static final int MSG_USER_INFO_CHANGED = 317;
128 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700129 private static final int MSG_STARTED_WAKING_UP = 319;
130 private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700131 private static final int MSG_STARTED_GOING_TO_SLEEP = 321;
Adrian Roosb6011622014-05-14 15:52:53 +0200132 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700133 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
134 private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
Jason Monk052082c2015-06-11 11:35:23 -0400135 private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
Etan Cohen47051d82015-07-06 16:19:04 -0700136 private static final int MSG_SERVICE_STATE_CHANGE = 330;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700137 private static final int MSG_SCREEN_TURNED_ON = 331;
138 private static final int MSG_SCREEN_TURNED_OFF = 332;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800139
Jorim Jaggi86bed402015-08-20 18:20:02 -0700140 /** Fingerprint state: Not listening to fingerprint. */
141 private static final int FINGERPRINT_STATE_STOPPED = 0;
142
143 /** Fingerprint state: Listening. */
144 private static final int FINGERPRINT_STATE_RUNNING = 1;
145
146 /**
147 * Fingerprint state: Cancelling and waiting for the confirmation from FingerprintService to
148 * send us the confirmation that cancellation has happened.
149 */
150 private static final int FINGERPRINT_STATE_CANCELLING = 2;
151
152 /**
153 * Fingerprint state: During cancelling we got another request to start listening, so when we
154 * receive the cancellation done signal, we should start listening again.
155 */
156 private static final int FINGERPRINT_STATE_CANCELLING_RESTARTING = 3;
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;
Jim Millerbbf1a742012-07-17 18:30:30 -0700176
Jim Millerdcb3d842012-08-23 19:18:12 -0700177 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700178 private boolean mDeviceProvisioned;
179
Jim Millerdcb3d842012-08-23 19:18:12 -0700180 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700181 private BatteryStatus mBatteryStatus;
182
Jim Millerdcb3d842012-08-23 19:18:12 -0700183 // Password attempts
Jorim Jaggi9f743032015-05-04 15:22:40 -0700184 private SparseIntArray mFailedAttempts = new SparseIntArray();
Brian Colonnacc4104f2012-10-09 17:50:46 -0400185
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700186 /** Tracks whether strong authentication hasn't been used since quite some time per user. */
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700187 private ArraySet<Integer> mStrongAuthNotTimedOut = new ArraySet<>();
Adrian Roosb5e47222015-08-14 15:53:06 -0700188 private final StrongAuthTracker mStrongAuthTracker = new StrongAuthTracker();
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;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700199 private AlarmManager mAlarmManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800200 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700201 private TrustManager mTrustManager;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700202 private int mFingerprintRunningState = FINGERPRINT_STATE_STOPPED;
Jim Miller20daffd2013-10-07 14:59:53 -0700203
Jim Millerbbf1a742012-07-17 18:30:30 -0700204 private final Handler mHandler = new Handler() {
205 @Override
206 public void handleMessage(Message msg) {
207 switch (msg.what) {
208 case MSG_TIME_UPDATE:
209 handleTimeUpdate();
210 break;
211 case MSG_BATTERY_UPDATE:
212 handleBatteryUpdate((BatteryStatus) msg.obj);
213 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700214 case MSG_SIM_STATE_CHANGE:
Jim Miller52a61332014-11-12 19:29:51 -0800215 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700216 break;
217 case MSG_RINGER_MODE_CHANGED:
218 handleRingerModeChange(msg.arg1);
219 break;
220 case MSG_PHONE_STATE_CHANGED:
Adrian Roosb6011622014-05-14 15:52:53 +0200221 handlePhoneStateChanged((String) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700222 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700223 case MSG_DEVICE_PROVISIONED:
224 handleDeviceProvisioned();
225 break;
226 case MSG_DPM_STATE_CHANGED:
227 handleDevicePolicyManagerStateChanged();
228 break;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500229 case MSG_USER_SWITCHING:
Adrian Roosb6011622014-05-14 15:52:53 +0200230 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
Chris Wrenf41c61b2012-11-29 15:19:54 -0500231 break;
232 case MSG_USER_SWITCH_COMPLETE:
233 handleUserSwitchComplete(msg.arg1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700234 break;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700235 case MSG_KEYGUARD_RESET:
236 handleKeyguardReset();
237 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200238 case MSG_KEYGUARD_BOUNCER_CHANGED:
239 handleKeyguardBouncerChanged(msg.arg1);
240 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800241 case MSG_BOOT_COMPLETED:
242 handleBootCompleted();
243 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700244 case MSG_USER_INFO_CHANGED:
245 handleUserInfoChanged(msg.arg1);
246 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400247 case MSG_REPORT_EMERGENCY_CALL_ACTION:
248 handleReportEmergencyCallAction();
249 break;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700250 case MSG_STARTED_GOING_TO_SLEEP:
251 handleStartedGoingToSleep(msg.arg1);
252 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700253 case MSG_FINISHED_GOING_TO_SLEEP:
254 handleFinishedGoingToSleep(msg.arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700255 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700256 case MSG_STARTED_WAKING_UP:
257 handleStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -0700258 break;
Jorim Jaggie7b12522014-08-06 16:41:21 +0200259 case MSG_FACE_UNLOCK_STATE_CHANGED:
Adrian Roos4a410172014-08-20 17:41:44 +0200260 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200261 break;
Jim Miller52a61332014-11-12 19:29:51 -0800262 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
263 handleSimSubscriptionInfoChanged();
264 break;
Jason Monk052082c2015-06-11 11:35:23 -0400265 case MSG_AIRPLANE_MODE_CHANGED:
266 handleAirplaneModeChanged();
267 break;
Etan Cohen47051d82015-07-06 16:19:04 -0700268 case MSG_SERVICE_STATE_CHANGE:
269 handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
270 break;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700271 case MSG_SCREEN_TURNED_ON:
272 handleScreenTurnedOn();
273 break;
274 case MSG_SCREEN_TURNED_OFF:
275 handleScreenTurnedOff();
276 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700277 }
278 }
279 };
280
Wink Savilled09c4ca2014-11-22 10:08:16 -0800281 private OnSubscriptionsChangedListener mSubscriptionListener =
282 new OnSubscriptionsChangedListener() {
Jim Miller52a61332014-11-12 19:29:51 -0800283 @Override
Wink Savilled09c4ca2014-11-22 10:08:16 -0800284 public void onSubscriptionsChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800285 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
286 }
287 };
288
Adrian Roos46842d92014-03-27 14:58:03 +0100289 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200290 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Jim Miller9f0753f2015-03-23 23:59:22 -0700291 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200292 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100293
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700294 private static int sCurrentUser;
295
296 public synchronized static void setCurrentUser(int currentUser) {
297 sCurrentUser = currentUser;
298 }
299
300 public synchronized static int getCurrentUser() {
301 return sCurrentUser;
302 }
303
Adrian Roos46842d92014-03-27 14:58:03 +0100304 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700305 public void onTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos46842d92014-03-27 14:58:03 +0100306 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200307 for (int i = 0; i < mCallbacks.size(); i++) {
308 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
309 if (cb != null) {
310 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700311 if (enabled && flags != 0) {
312 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200313 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200314 }
315 }
Adrian Roos46842d92014-03-27 14:58:03 +0100316 }
317
Jim Miller52a61332014-11-12 19:29:51 -0800318 protected void handleSimSubscriptionInfoChanged() {
319 if (DEBUG_SIM_STATES) {
320 Log.v(TAG, "onSubscriptionInfoChanged()");
Wink Savilled09c4ca2014-11-22 10:08:16 -0800321 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
322 if (sil != null) {
323 for (SubscriptionInfo subInfo : sil) {
324 Log.v(TAG, "SubInfo:" + subInfo);
325 }
326 } else {
327 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800328 }
329 }
330 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
331
332 // Hack level over 9000: Because the subscription id is not yet valid when we see the
333 // first update in handleSimStateChange, we need to force refresh all all SIM states
334 // so the subscription id for them is consistent.
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100335 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
Jim Miller52a61332014-11-12 19:29:51 -0800336 for (int i = 0; i < subscriptionInfos.size(); i++) {
337 SubscriptionInfo info = subscriptionInfos.get(i);
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100338 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
339 if (changed) {
340 changedSubscriptions.add(info);
341 }
Jim Miller52a61332014-11-12 19:29:51 -0800342 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100343 for (int i = 0; i < changedSubscriptions.size(); i++) {
344 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800345 for (int j = 0; j < mCallbacks.size(); j++) {
346 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
347 if (cb != null) {
348 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
349 }
350 }
351 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500352 for (int j = 0; j < mCallbacks.size(); j++) {
353 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
354 if (cb != null) {
355 cb.onRefreshCarrierInfo();
356 }
357 }
Jim Miller52a61332014-11-12 19:29:51 -0800358 }
359
Jason Monk052082c2015-06-11 11:35:23 -0400360 private void handleAirplaneModeChanged() {
361 for (int j = 0; j < mCallbacks.size(); j++) {
362 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
363 if (cb != null) {
364 cb.onRefreshCarrierInfo();
365 }
366 }
367 }
368
Wink Savilled09c4ca2014-11-22 10:08:16 -0800369 /** @return List of SubscriptionInfo records, maybe empty but never null */
Jim Miller52a61332014-11-12 19:29:51 -0800370 List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800371 List<SubscriptionInfo> sil = mSubscriptionInfo;
372 if (sil == null || forceReload) {
373 sil = mSubscriptionManager.getActiveSubscriptionInfoList();
374 }
375 if (sil == null) {
376 // getActiveSubscriptionInfoList was null callers expect an empty list.
377 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
378 } else {
379 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800380 }
381 return mSubscriptionInfo;
382 }
383
Adrian Roos7861c662014-07-25 15:37:28 +0200384 @Override
385 public void onTrustManagedChanged(boolean managed, int userId) {
386 mUserTrustIsManaged.put(userId, managed);
387
388 for (int i = 0; i < mCallbacks.size(); i++) {
389 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
390 if (cb != null) {
391 cb.onTrustManagedChanged(userId);
392 }
393 }
394 }
395
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700396 private void onFingerprintAuthenticated(int userId) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700397 mUserFingerprintAuthenticated.put(userId, true);
Jorim Jaggi71448a72015-08-18 19:49:04 -0700398
399 // If fingerprint unlocking is allowed, this event will lead to a Keyguard dismiss or to a
400 // wake-up (if Keyguard is not showing), so we don't need to listen until Keyguard is
401 // fully gone.
402 mFingerprintAlreadyAuthenticated = isUnlockingWithFingerprintAllowed();
Jim Millerf41fc962014-06-18 16:33:51 -0700403 for (int i = 0; i < mCallbacks.size(); i++) {
404 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
405 if (cb != null) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700406 cb.onFingerprintAuthenticated(userId);
Jim Millerf41fc962014-06-18 16:33:51 -0700407 }
408 }
409 }
410
Jim Millerce7eb6d2015-04-03 19:29:13 -0700411 private void handleFingerprintAuthFailed() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700412 for (int i = 0; i < mCallbacks.size(); i++) {
413 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
414 if (cb != null) {
415 cb.onFingerprintAuthFailed();
416 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700417 }
Jim Millerce7eb6d2015-04-03 19:29:13 -0700418 handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized));
419 }
Jim Millerf41fc962014-06-18 16:33:51 -0700420
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700421 private void handleFingerprintAcquired(int acquireInfo) {
422 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
423 return;
424 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700425 for (int i = 0; i < mCallbacks.size(); i++) {
426 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
427 if (cb != null) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700428 cb.onFingerprintAcquired();
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700429 }
430 }
431 }
432
Jim Miller4f364c92015-06-08 19:24:13 -0700433 private void handleFingerprintAuthenticated() {
Jim Millerf41fc962014-06-18 16:33:51 -0700434 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700435 final int userId;
436 try {
437 userId = ActivityManagerNative.getDefault().getCurrentUser().id;
438 } catch (RemoteException e) {
439 Log.e(TAG, "Failed to get current user id: ", e);
440 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700441 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700442 if (isFingerprintDisabled(userId)) {
443 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
444 return;
445 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700446 onFingerprintAuthenticated(userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700447 } finally {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700448 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
Jim Millerf41fc962014-06-18 16:33:51 -0700449 }
450 }
451
Jim Miller9f0753f2015-03-23 23:59:22 -0700452 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700453 for (int i = 0; i < mCallbacks.size(); i++) {
454 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
455 if (cb != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700456 cb.onFingerprintHelp(msgId, helpString);
457 }
458 }
459 }
460
461 private void handleFingerprintError(int msgId, String errString) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700462 if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
463 && mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
464 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
465 startListeningForFingerprint();
466 } else {
467 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
468 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700469 for (int i = 0; i < mCallbacks.size(); i++) {
470 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
471 if (cb != null) {
472 cb.onFingerprintError(msgId, errString);
Jim Millerf41fc962014-06-18 16:33:51 -0700473 }
474 }
475 }
476
Jorim Jaggi3a464782015-08-28 16:59:13 -0700477 private void handleFingerprintLockoutReset() {
478 updateFingerprintListeningState();
479 }
480
Jorim Jaggi86bed402015-08-20 18:20:02 -0700481 private void setFingerprintRunningState(int fingerprintRunningState) {
482 boolean wasRunning = mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
483 boolean isRunning = fingerprintRunningState == FINGERPRINT_STATE_RUNNING;
484 mFingerprintRunningState = fingerprintRunningState;
485
486 // Clients of KeyguardUpdateMonitor don't care about the internal state about the
487 // asynchronousness of the cancel cycle. So only notify them if the actualy running state
488 // has changed.
489 if (wasRunning != isRunning) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700490 notifyFingerprintRunningStateChanged();
491 }
492 }
493
494 private void notifyFingerprintRunningStateChanged() {
495 for (int i = 0; i < mCallbacks.size(); i++) {
496 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
497 if (cb != null) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700498 cb.onFingerprintRunningStateChanged(isFingerprintDetectionRunning());
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700499 }
500 }
501 }
Adrian Roos4a410172014-08-20 17:41:44 +0200502 private void handleFaceUnlockStateChanged(boolean running, int userId) {
503 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200504 for (int i = 0; i < mCallbacks.size(); i++) {
505 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
506 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200507 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200508 }
509 }
510 }
511
Adrian Roos4a410172014-08-20 17:41:44 +0200512 public boolean isFaceUnlockRunning(int userId) {
513 return mUserFaceUnlockRunning.get(userId);
514 }
515
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700516 public boolean isFingerprintDetectionRunning() {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700517 return mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700518 }
519
Jim Miller50e62182014-04-23 17:25:00 -0700520 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100521 // Don't allow trust agent if device is secured with a SIM PIN. This is here
522 // mainly because there's no other way to prompt the user to enter their SIM PIN
523 // once they get past the keyguard screen.
524 final boolean disabledBySimPin = isSimPinSecure();
525 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700526 }
527
Jim Miller06e34502014-07-17 14:46:05 -0700528 private boolean isFingerprintDisabled(int userId) {
529 final DevicePolicyManager dpm =
530 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
531 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
Adrian Roos733b6632015-08-21 14:32:35 -0700532 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0
533 || isSimPinSecure();
Jim Miller06e34502014-07-17 14:46:05 -0700534 }
535
Selim Cineke8bae622015-07-15 13:24:06 -0700536 public boolean getUserCanSkipBouncer(int userId) {
Selim Cinek1fcafc42015-07-20 14:39:25 -0700537 return getUserHasTrust(userId) || (mUserFingerprintAuthenticated.get(userId)
538 && isUnlockingWithFingerprintAllowed());
Selim Cineke8bae622015-07-15 13:24:06 -0700539 }
540
Adrian Roos46842d92014-03-27 14:58:03 +0100541 public boolean getUserHasTrust(int userId) {
Selim Cineke8bae622015-07-15 13:24:06 -0700542 return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100543 }
544
Adrian Roos7861c662014-07-25 15:37:28 +0200545 public boolean getUserTrustIsManaged(int userId) {
546 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
547 }
548
Selim Cinek1fcafc42015-07-20 14:39:25 -0700549 public boolean isUnlockingWithFingerprintAllowed() {
Adrian Roosb5e47222015-08-14 15:53:06 -0700550 return mStrongAuthTracker.isUnlockingWithFingerprintAllowed()
551 && !hasFingerprintUnlockTimedOut(sCurrentUser);
552 }
553
554 public StrongAuthTracker getStrongAuthTracker() {
555 return mStrongAuthTracker;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700556 }
557
558 /**
559 * @return true if the user hasn't use strong authentication (pattern, PIN, password) since a
560 * while and thus can't unlock with fingerprint, false otherwise
561 */
562 public boolean hasFingerprintUnlockTimedOut(int userId) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700563 return !mStrongAuthNotTimedOut.contains(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700564 }
565
566 public void reportSuccessfulStrongAuthUnlockAttempt() {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700567 mStrongAuthNotTimedOut.add(sCurrentUser);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700568 scheduleStrongAuthTimeout();
Jim Millere0507bb2015-08-12 20:30:34 -0700569 if (mFpm != null) {
570 byte[] token = null; /* TODO: pass real auth token once fp HAL supports it */
571 mFpm.resetTimeout(token);
572 }
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700573 }
574
575 private void scheduleStrongAuthTimeout() {
576 long when = SystemClock.elapsedRealtime() + FINGERPRINT_UNLOCK_TIMEOUT_MS;
577 Intent intent = new Intent(ACTION_STRONG_AUTH_TIMEOUT);
578 intent.putExtra(USER_ID, sCurrentUser);
579 PendingIntent sender = PendingIntent.getBroadcast(mContext,
580 sCurrentUser, intent, PendingIntent.FLAG_CANCEL_CURRENT);
581 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, sender);
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700582 notifyStrongAuthStateChanged(sCurrentUser);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700583 }
584
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700585 private void notifyStrongAuthStateChanged(int userId) {
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700586 for (int i = 0; i < mCallbacks.size(); i++) {
587 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
588 if (cb != null) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700589 cb.onStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700590 }
591 }
Selim Cinek1fcafc42015-07-20 14:39:25 -0700592 }
593
Jim Miller8f09fd22013-03-14 19:04:28 -0700594 static class DisplayClientState {
595 public int clientGeneration;
596 public boolean clearing;
597 public PendingIntent intent;
598 public int playbackState;
599 public long playbackEventTime;
600 }
601
602 private DisplayClientState mDisplayClientState = new DisplayClientState();
603
Jim Millerbbf1a742012-07-17 18:30:30 -0700604 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
605
606 public void onReceive(Context context, Intent intent) {
607 final String action = intent.getAction();
608 if (DEBUG) Log.d(TAG, "received broadcast " + action);
609
610 if (Intent.ACTION_TIME_TICK.equals(action)
611 || Intent.ACTION_TIME_CHANGED.equals(action)
Adrian Roos48c796c2014-09-01 14:59:23 +0200612 || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700613 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Jim Millerbbf1a742012-07-17 18:30:30 -0700614 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
615 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
616 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
617 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
618 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
Adrian Roos7b043112015-07-10 13:00:33 -0700619 final int maxChargingCurrent = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700620 final Message msg = mHandler.obtainMessage(
Adrian Roos7b043112015-07-10 13:00:33 -0700621 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
622 maxChargingCurrent));
Jim Millerbbf1a742012-07-17 18:30:30 -0700623 mHandler.sendMessage(msg);
624 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Jim Miller52a61332014-11-12 19:29:51 -0800625 SimData args = SimData.fromIntent(intent);
Jim Millerbbf1a742012-07-17 18:30:30 -0700626 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -0800627 Log.v(TAG, "action " + action
628 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
629 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -0700630 }
Jim Miller52a61332014-11-12 19:29:51 -0800631 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
632 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -0700633 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
634 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
635 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
636 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
637 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
638 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Jason Monk052082c2015-06-11 11:35:23 -0400639 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
640 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800641 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700642 dispatchBootCompleted();
Etan Cohen47051d82015-07-06 16:19:04 -0700643 } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
644 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
645 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
646 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
647 if (DEBUG) {
648 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
649 + subId);
650 }
651 mHandler.sendMessage(
652 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
Jim Millerbbf1a742012-07-17 18:30:30 -0700653 }
654 }
655 };
Jim Miller2de5ee82012-06-14 22:22:50 -0700656
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700657 private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
658
659 public void onReceive(Context context, Intent intent) {
660 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +0200661 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
662 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
663 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700664 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
665 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +0200666 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
667 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
668 getSendingUserId()));
669 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
670 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
671 getSendingUserId()));
672 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
673 .equals(action)) {
674 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700675 }
676 }
677 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700678
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700679 private final BroadcastReceiver mStrongAuthTimeoutReceiver = new BroadcastReceiver() {
680 @Override
681 public void onReceive(Context context, Intent intent) {
682 if (ACTION_STRONG_AUTH_TIMEOUT.equals(intent.getAction())) {
683 int userId = intent.getIntExtra(USER_ID, -1);
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700684 mStrongAuthNotTimedOut.remove(userId);
685 notifyStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700686 }
687 }
688 };
689
Jorim Jaggi3a464782015-08-28 16:59:13 -0700690 private final FingerprintManager.LockoutResetCallback mLockoutResetCallback
691 = new FingerprintManager.LockoutResetCallback() {
692 @Override
693 public void onLockoutReset() {
694 handleFingerprintLockoutReset();
695 }
696 };
697
Jim Miller9f0753f2015-03-23 23:59:22 -0700698 private FingerprintManager.AuthenticationCallback mAuthenticationCallback
699 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -0700700
701 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -0700702 public void onAuthenticationFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700703 handleFingerprintAuthFailed();
Jim Millerce7eb6d2015-04-03 19:29:13 -0700704 };
705
706 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700707 public void onAuthenticationSucceeded(AuthenticationResult result) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700708 handleFingerprintAuthenticated();
Jim Millerf41fc962014-06-18 16:33:51 -0700709 }
710
711 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700712 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700713 handleFingerprintHelp(helpMsgId, helpString.toString());
Jim Miller9f0753f2015-03-23 23:59:22 -0700714 }
715
716 @Override
717 public void onAuthenticationError(int errMsgId, CharSequence errString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700718 handleFingerprintError(errMsgId, errString.toString());
719 }
720
721 @Override
722 public void onAuthenticationAcquired(int acquireInfo) {
723 handleFingerprintAcquired(acquireInfo);
Jim Millerf41fc962014-06-18 16:33:51 -0700724 }
725 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700726 private CancellationSignal mFingerprintCancelSignal;
727 private FingerprintManager mFpm;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700728
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800729 /**
Jim Miller47088bb2009-11-24 00:40:16 -0800730 * When we receive a
731 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -0700732 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800733 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -0800734 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800735 */
Jim Miller52a61332014-11-12 19:29:51 -0800736 private static class SimData {
737 public State simState;
738 public int slotId;
739 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800740
Jim Miller52a61332014-11-12 19:29:51 -0800741 SimData(State state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -0800742 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -0800743 slotId = slot;
744 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -0800745 }
746
Jim Miller52a61332014-11-12 19:29:51 -0800747 static SimData fromIntent(Intent intent) {
748 State state;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800749 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
750 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
751 }
Wink Savillea639b312012-07-10 12:37:54 -0700752 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
Jim Miller52a61332014-11-12 19:29:51 -0800753 int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0);
754 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
Wink Savilled09c4ca2014-11-22 10:08:16 -0800755 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea639b312012-07-10 12:37:54 -0700756 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -0700757 final String absentReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700758 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -0700759
Wink Savillea639b312012-07-10 12:37:54 -0700760 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -0700761 absentReason)) {
Wink Savillea639b312012-07-10 12:37:54 -0700762 state = IccCardConstants.State.PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -0700763 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700764 state = IccCardConstants.State.ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -0700765 }
Wink Savillea639b312012-07-10 12:37:54 -0700766 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
767 state = IccCardConstants.State.READY;
768 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800769 final String lockedReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700770 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
771 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
772 state = IccCardConstants.State.PIN_REQUIRED;
773 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
774 state = IccCardConstants.State.PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800775 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700776 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800777 }
Wink Savillea639b312012-07-10 12:37:54 -0700778 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
779 state = IccCardConstants.State.NETWORK_LOCKED;
Jim Miller109f1fd2012-09-19 20:44:16 -0700780 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
781 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
782 // This is required because telephony doesn't return to "READY" after
783 // these state transitions. See bug 7197471.
784 state = IccCardConstants.State.READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800785 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700786 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800787 }
Jim Miller52a61332014-11-12 19:29:51 -0800788 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800789 }
790
791 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -0800792 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800793 }
794 }
795
Adrian Roos12c1ef52014-06-04 13:54:08 +0200796 public static class BatteryStatus {
Adrian Roos7b043112015-07-10 13:00:33 -0700797 public static final int CHARGING_UNKNOWN = -1;
798 public static final int CHARGING_SLOWLY = 0;
799 public static final int CHARGING_REGULAR = 1;
800 public static final int CHARGING_FAST = 2;
801
Jim Miller16464b82011-10-20 21:10:13 -0700802 public final int status;
803 public final int level;
804 public final int plugged;
805 public final int health;
Adrian Roos7b043112015-07-10 13:00:33 -0700806 public final int maxChargingCurrent;
807 public BatteryStatus(int status, int level, int plugged, int health, int maxChargingCurrent) {
Jim Miller16464b82011-10-20 21:10:13 -0700808 this.status = status;
809 this.level = level;
810 this.plugged = plugged;
811 this.health = health;
Adrian Roos7b043112015-07-10 13:00:33 -0700812 this.maxChargingCurrent = maxChargingCurrent;
Jim Miller16464b82011-10-20 21:10:13 -0700813 }
814
Jim Millerbbf1a742012-07-17 18:30:30 -0700815 /**
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700816 * Determine whether the device is plugged in (USB, power, or wireless).
Jim Millerbbf1a742012-07-17 18:30:30 -0700817 * @return true if the device is plugged in.
818 */
Adrian Roosad3bc7f2014-10-30 18:29:38 +0100819 public boolean isPluggedIn() {
Jim Millerbbf1a742012-07-17 18:30:30 -0700820 return plugged == BatteryManager.BATTERY_PLUGGED_AC
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700821 || plugged == BatteryManager.BATTERY_PLUGGED_USB
822 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Jim Millerbbf1a742012-07-17 18:30:30 -0700823 }
824
825 /**
826 * Whether or not the device is charged. Note that some devices never return 100% for
827 * battery level, so this allows either battery level or status to determine if the
828 * battery is charged.
829 * @return true if the device is charged
830 */
831 public boolean isCharged() {
832 return status == BATTERY_STATUS_FULL || level >= 100;
833 }
834
835 /**
836 * Whether battery is low and needs to be charged.
837 * @return true if battery is low
838 */
839 public boolean isBatteryLow() {
840 return level < LOW_BATTERY_THRESHOLD;
841 }
842
Adrian Roos7b043112015-07-10 13:00:33 -0700843 public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
844 return maxChargingCurrent <= 0 ? CHARGING_UNKNOWN :
845 maxChargingCurrent < slowThreshold ? CHARGING_SLOWLY :
846 maxChargingCurrent > fastThreshold ? CHARGING_FAST :
847 CHARGING_REGULAR;
848 }
Jim Miller16464b82011-10-20 21:10:13 -0700849 }
850
Adrian Roosb5e47222015-08-14 15:53:06 -0700851 public class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
852
853 public boolean isUnlockingWithFingerprintAllowed() {
854 int userId = getCurrentUser();
855 return isFingerprintAllowedForUser(userId);
856 }
857
858 public boolean hasUserAuthenticatedSinceBoot() {
859 int userId = getCurrentUser();
860 return (getStrongAuthForUser(userId)
861 & STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
862 }
863
864 @Override
865 public void onStrongAuthRequiredChanged(int userId) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700866 notifyStrongAuthStateChanged(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -0700867 }
868 }
869
Jim Millerdcb3d842012-08-23 19:18:12 -0700870 public static KeyguardUpdateMonitor getInstance(Context context) {
871 if (sInstance == null) {
872 sInstance = new KeyguardUpdateMonitor(context);
873 }
874 return sInstance;
875 }
876
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700877 protected void handleStartedWakingUp() {
Jorim Jaggi864e64b2015-05-20 14:13:23 -0700878 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -0700879 final int count = mCallbacks.size();
880 for (int i = 0; i < count; i++) {
881 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
882 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700883 cb.onStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -0700884 }
885 }
886 }
887
Jorim Jaggi95e40382015-09-16 15:53:42 -0700888 protected void handleStartedGoingToSleep(int arg1) {
Jim Millerf41fc962014-06-18 16:33:51 -0700889 clearFingerprintRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -0700890 final int count = mCallbacks.size();
891 for (int i = 0; i < count; i++) {
892 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
893 if (cb != null) {
Jorim Jaggi95e40382015-09-16 15:53:42 -0700894 cb.onStartedGoingToSleep(arg1);
895 }
896 }
897 mGoingToSleep = true;
898 mFingerprintAlreadyAuthenticated = false;
899 updateFingerprintListeningState();
900 }
901
902 protected void handleFinishedGoingToSleep(int arg1) {
903 mGoingToSleep = false;
904 final int count = mCallbacks.size();
905 for (int i = 0; i < count; i++) {
906 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
907 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700908 cb.onFinishedGoingToSleep(arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700909 }
910 }
Jorim Jaggiea657062015-04-28 13:45:11 -0700911 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -0700912 }
913
Jorim Jaggif1518da2015-07-30 11:56:36 -0700914 private void handleScreenTurnedOn() {
915 final int count = mCallbacks.size();
916 for (int i = 0; i < count; i++) {
917 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
918 if (cb != null) {
919 cb.onScreenTurnedOn();
920 }
921 }
922 }
923
924 private void handleScreenTurnedOff() {
925 final int count = mCallbacks.size();
926 for (int i = 0; i < count; i++) {
927 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
928 if (cb != null) {
929 cb.onScreenTurnedOff();
930 }
931 }
932 }
933
Adam Powell43a372f2013-09-27 17:43:53 -0700934 /**
935 * IMPORTANT: Must be called from UI thread.
936 */
937 public void dispatchSetBackground(Bitmap bmp) {
938 if (DEBUG) Log.d(TAG, "dispatchSetBackground");
939 final int count = mCallbacks.size();
940 for (int i = 0; i < count; i++) {
941 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
942 if (cb != null) {
943 cb.onSetBackground(bmp);
944 }
945 }
946 }
947
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700948 private void handleUserInfoChanged(int userId) {
949 for (int i = 0; i < mCallbacks.size(); i++) {
950 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
951 if (cb != null) {
952 cb.onUserInfoChanged(userId);
953 }
954 }
955 }
956
Jim Millerdcb3d842012-08-23 19:18:12 -0700957 private KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800958 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800959 mSubscriptionManager = SubscriptionManager.from(context);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700960 mAlarmManager = context.getSystemService(AlarmManager.class);
Michael Jurkafff56142012-11-28 16:51:00 -0800961 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700962
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800963 // Since device can't be un-provisioned, we only need to register a content observer
964 // to update mDeviceProvisioned when we are...
965 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700966 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800967 }
Jim Miller47088bb2009-11-24 00:40:16 -0800968
Jim Millerbbf1a742012-07-17 18:30:30 -0700969 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Adrian Roos7b043112015-07-10 13:00:33 -0700970 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800971
Jim Millerbbf1a742012-07-17 18:30:30 -0700972 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800973 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800974 filter.addAction(Intent.ACTION_TIME_TICK);
975 filter.addAction(Intent.ACTION_TIME_CHANGED);
976 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
977 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Jason Monk052082c2015-06-11 11:35:23 -0400978 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800979 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Etan Cohen47051d82015-07-06 16:19:04 -0700980 filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -0800981 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -0800982 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Jim Millerbbf1a742012-07-17 18:30:30 -0700983 context.registerReceiver(mBroadcastReceiver, filter);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700984
Adam Cohenc276e822012-11-08 13:01:08 -0800985 final IntentFilter bootCompleteFilter = new IntentFilter();
986 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
987 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
988 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter);
989
Adrian Roos48c796c2014-09-01 14:59:23 +0200990 final IntentFilter allUserFilter = new IntentFilter();
991 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
992 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
993 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
994 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
995 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
996 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700997 null, null);
998
Wink Saville071743f2015-01-12 17:11:04 -0800999 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001000 try {
1001 ActivityManagerNative.getDefault().registerUserSwitchObserver(
1002 new IUserSwitchObserver.Stub() {
1003 @Override
1004 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001005 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001006 newUserId, 0, reply));
1007 }
1008 @Override
1009 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001010 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +02001011 newUserId, 0));
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001012 }
Kenny Guy42979622015-04-13 18:03:05 +00001013 @Override
1014 public void onForegroundProfileSwitch(int newProfileId) {
1015 // Ignore.
1016 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001017 });
1018 } catch (RemoteException e) {
1019 // TODO Auto-generated catch block
1020 e.printStackTrace();
1021 }
Adrian Roos46842d92014-03-27 14:58:03 +01001022
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001023 IntentFilter strongAuthTimeoutFilter = new IntentFilter();
1024 strongAuthTimeoutFilter.addAction(ACTION_STRONG_AUTH_TIMEOUT);
1025 context.registerReceiver(mStrongAuthTimeoutReceiver, strongAuthTimeoutFilter,
1026 PERMISSION_SELF, null /* handler */);
Jorim Jaggi237b0612015-05-01 14:28:49 -07001027 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
1028 mTrustManager.registerTrustListener(this);
Adrian Roosb5e47222015-08-14 15:53:06 -07001029 new LockPatternUtils(context).registerStrongAuthTracker(mStrongAuthTracker);
Jim Millerf41fc962014-06-18 16:33:51 -07001030
Jim Miller9f0753f2015-03-23 23:59:22 -07001031 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
Jorim Jaggiea657062015-04-28 13:45:11 -07001032 updateFingerprintListeningState();
Jorim Jaggi3a464782015-08-28 16:59:13 -07001033 if (mFpm != null) {
1034 mFpm.addLockoutResetCallback(mLockoutResetCallback);
1035 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001036 }
1037
1038 private void updateFingerprintListeningState() {
1039 boolean shouldListenForFingerprint = shouldListenForFingerprint();
Jorim Jaggi86bed402015-08-20 18:20:02 -07001040 if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING && !shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001041 stopListeningForFingerprint();
Jorim Jaggi86bed402015-08-20 18:20:02 -07001042 } else if (mFingerprintRunningState != FINGERPRINT_STATE_RUNNING
1043 && shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001044 startListeningForFingerprint();
1045 }
1046 }
1047
1048 private boolean shouldListenForFingerprint() {
Jorim Jaggi95e40382015-09-16 15:53:42 -07001049 return (mKeyguardIsVisible || !mDeviceInteractive || mBouncer || mGoingToSleep)
1050 && !mSwitchingUser && !mFingerprintAlreadyAuthenticated
1051 && !isFingerprintDisabled(getCurrentUser());
Jim Miller9f0753f2015-03-23 23:59:22 -07001052 }
1053
Jim Millerce7eb6d2015-04-03 19:29:13 -07001054 private void startListeningForFingerprint() {
Jorim Jaggi86bed402015-08-20 18:20:02 -07001055 if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING) {
1056 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING_RESTARTING);
1057 return;
1058 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001059 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -07001060 int userId = ActivityManager.getCurrentUser();
Jorim Jaggi71448a72015-08-18 19:49:04 -07001061 if (isUnlockWithFingerprintPossible(userId)) {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001062 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001063 mFingerprintCancelSignal.cancel();
1064 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001065 mFingerprintCancelSignal = new CancellationSignal();
Jim Millerf501b582015-06-03 16:36:31 -07001066 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null, userId);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001067 setFingerprintRunningState(FINGERPRINT_STATE_RUNNING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001068 }
1069 }
1070
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001071 public boolean isUnlockWithFingerprintPossible(int userId) {
Selim Cinek3122fa82015-06-18 01:38:59 -07001072 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
1073 && mFpm.getEnrolledFingerprints(userId).size() > 0;
1074 }
1075
Jorim Jaggiea657062015-04-28 13:45:11 -07001076 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001077 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
Jorim Jaggi86bed402015-08-20 18:20:02 -07001078 if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001079 mFingerprintCancelSignal.cancel();
Jim Millerce7eb6d2015-04-03 19:29:13 -07001080 mFingerprintCancelSignal = null;
Jorim Jaggi86bed402015-08-20 18:20:02 -07001081 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001082 }
Jorim Jaggi86bed402015-08-20 18:20:02 -07001083 if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
1084 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
1085 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001086 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001087
Michael Jurkafff56142012-11-28 16:51:00 -08001088 private boolean isDeviceProvisionedInSettingsDb() {
1089 return Settings.Global.getInt(mContext.getContentResolver(),
1090 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1091 }
1092
Jim Millerbbf1a742012-07-17 18:30:30 -07001093 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -08001094 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001095 @Override
1096 public void onChange(boolean selfChange) {
1097 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -08001098 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001099 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001100 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001101 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001102 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001103 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001104 };
1105
1106 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -07001107 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -08001108 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -07001109
1110 // prevent a race condition between where we check the flag and where we register the
1111 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -08001112 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001113 if (provisioned != mDeviceProvisioned) {
1114 mDeviceProvisioned = provisioned;
1115 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001116 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001117 }
1118 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001119 }
1120
Jim Millerbbf1a742012-07-17 18:30:30 -07001121 /**
1122 * Handle {@link #MSG_DPM_STATE_CHANGED}
1123 */
Jim Millerb0304762012-03-13 20:01:25 -07001124 protected void handleDevicePolicyManagerStateChanged() {
Adrian Roos733b6632015-08-21 14:32:35 -07001125 updateFingerprintListeningState();
Jim Millerdcb3d842012-08-23 19:18:12 -07001126 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1127 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1128 if (cb != null) {
1129 cb.onDevicePolicyManagerStateChanged();
1130 }
Jim Millerb0304762012-03-13 20:01:25 -07001131 }
1132 }
1133
Jim Millerbbf1a742012-07-17 18:30:30 -07001134 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001135 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -07001136 */
Chris Wrenf41c61b2012-11-29 15:19:54 -05001137 protected void handleUserSwitching(int userId, IRemoteCallback reply) {
Jorim Jaggiaa4d32a2015-05-13 16:30:04 -07001138 mSwitchingUser = true;
1139 updateFingerprintListeningState();
1140
Jim Millerbbf1a742012-07-17 18:30:30 -07001141 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001142 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1143 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001144 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -07001145 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001146 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001147 try {
1148 reply.sendResult(null);
1149 } catch (RemoteException e) {
1150 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001151 }
1152
Jim Millerbbf1a742012-07-17 18:30:30 -07001153 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001154 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
1155 */
1156 protected void handleUserSwitchComplete(int userId) {
Jorim Jaggiaa4d32a2015-05-13 16:30:04 -07001157 mSwitchingUser = false;
1158 updateFingerprintListeningState();
1159
Chris Wrenf41c61b2012-11-29 15:19:54 -05001160 for (int i = 0; i < mCallbacks.size(); i++) {
1161 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1162 if (cb != null) {
1163 cb.onUserSwitchComplete(userId);
1164 }
1165 }
1166 }
1167
1168 /**
Jim Miller90873d52013-09-26 18:11:38 -07001169 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
1170 * keyguard crashes sometime after boot, then it will never receive this
1171 * broadcast and hence not handle the event. This method is ultimately called by
1172 * PhoneWindowManager in this case.
1173 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001174 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001175 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -07001176 }
1177
1178 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001179 * Handle {@link #MSG_BOOT_COMPLETED}
1180 */
1181 protected void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001182 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001183 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001184 for (int i = 0; i < mCallbacks.size(); i++) {
1185 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1186 if (cb != null) {
1187 cb.onBootCompleted();
1188 }
1189 }
1190 }
1191
1192 /**
Jim Miller5ecd8112013-01-09 18:50:26 -08001193 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001194 * destroyed.
1195 */
1196 public boolean hasBootCompleted() {
1197 return mBootCompleted;
1198 }
1199
1200 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001201 * Handle {@link #MSG_DEVICE_PROVISIONED}
1202 */
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001203 protected void handleDeviceProvisioned() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001204 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001205 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1206 if (cb != null) {
1207 cb.onDeviceProvisioned();
1208 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001209 }
Michael Jurkafff56142012-11-28 16:51:00 -08001210 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001211 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -08001212 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
1213 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001214 }
1215 }
1216
Jim Millerbbf1a742012-07-17 18:30:30 -07001217 /**
1218 * Handle {@link #MSG_PHONE_STATE_CHANGED}
1219 */
Jim Millerc23024d2010-02-24 15:37:00 -08001220 protected void handlePhoneStateChanged(String newState) {
1221 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001222 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
1223 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
1224 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
1225 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
1226 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
1227 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
1228 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001229 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001230 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1231 if (cb != null) {
1232 cb.onPhoneStateChanged(mPhoneState);
1233 }
Jim Millerc23024d2010-02-24 15:37:00 -08001234 }
1235 }
1236
Jim Millerbbf1a742012-07-17 18:30:30 -07001237 /**
1238 * Handle {@link #MSG_RINGER_MODE_CHANGED}
1239 */
Jim Miller47088bb2009-11-24 00:40:16 -08001240 protected void handleRingerModeChange(int mode) {
1241 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001242 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -07001243 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001244 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1245 if (cb != null) {
1246 cb.onRingerModeChanged(mode);
1247 }
Jim Miller47088bb2009-11-24 00:40:16 -08001248 }
1249 }
1250
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001251 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001252 * Handle {@link #MSG_TIME_UPDATE}
1253 */
1254 private void handleTimeUpdate() {
1255 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001256 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001257 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1258 if (cb != null) {
1259 cb.onTimeChanged();
1260 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001261 }
1262 }
1263
1264 /**
1265 * Handle {@link #MSG_BATTERY_UPDATE}
1266 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001267 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001268 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001269 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
1270 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07001271 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001272 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001273 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1274 if (cb != null) {
1275 cb.onRefreshBatteryInfo(status);
1276 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001277 }
1278 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001279 }
1280
1281 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001282 * Handle {@link #MSG_SIM_STATE_CHANGE}
1283 */
Jim Miller52a61332014-11-12 19:29:51 -08001284 private void handleSimStateChange(int subId, int slotId, State state) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001285
Jim Miller52a61332014-11-12 19:29:51 -08001286 if (DEBUG_SIM_STATES) {
1287 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
1288 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001289 }
1290
Wink Savillea54bf652014-12-11 13:37:50 -08001291 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08001292 Log.w(TAG, "invalid subId in handleSimStateChange()");
1293 return;
1294 }
1295
1296 SimData data = mSimDatas.get(subId);
1297 final boolean changed;
1298 if (data == null) {
1299 data = new SimData(state, slotId, subId);
1300 mSimDatas.put(subId, data);
1301 changed = true; // no data yet; force update
1302 } else {
1303 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
1304 data.simState = state;
1305 data.subId = subId;
1306 data.slotId = slotId;
1307 }
1308 if (changed && state != State.UNKNOWN) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001309 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001310 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1311 if (cb != null) {
Jim Miller52a61332014-11-12 19:29:51 -08001312 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07001313 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001314 }
1315 }
1316 }
1317
Jim Millerbbf1a742012-07-17 18:30:30 -07001318 /**
Etan Cohen47051d82015-07-06 16:19:04 -07001319 * Handle {@link #MSG_SERVICE_STATE_CHANGE}
1320 */
1321 private void handleServiceStateChange(int subId, ServiceState serviceState) {
1322 if (DEBUG) {
1323 Log.d(TAG,
1324 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
1325 }
1326
1327 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1328 Log.w(TAG, "invalid subId in handleServiceStateChange()");
1329 return;
1330 }
1331
1332 mServiceStates.put(subId, serviceState);
1333
1334 for (int j = 0; j < mCallbacks.size(); j++) {
1335 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
1336 if (cb != null) {
1337 cb.onRefreshCarrierInfo();
1338 }
1339 }
1340 }
1341
1342 /**
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001343 * Notifies that the visibility state of Keyguard has changed.
1344 *
1345 * <p>Needs to be called from the main thread.
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001346 */
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001347 public void onKeyguardVisibilityChanged(boolean showing) {
1348 if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
1349 mKeyguardIsVisible = showing;
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001350 for (int i = 0; i < mCallbacks.size(); i++) {
1351 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1352 if (cb != null) {
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001353 cb.onKeyguardVisibilityChangedRaw(showing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001354 }
1355 }
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001356 if (!showing) {
Jorim Jaggi71448a72015-08-18 19:49:04 -07001357 mFingerprintAlreadyAuthenticated = false;
1358 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001359 updateFingerprintListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001360 }
1361
Brian Colonna7fce3802013-09-17 15:51:32 -04001362 /**
Selim Cinek1fcafc42015-07-20 14:39:25 -07001363 * Handle {@link #MSG_KEYGUARD_RESET}
1364 */
1365 private void handleKeyguardReset() {
1366 if (DEBUG) Log.d(TAG, "handleKeyguardReset");
Adrian Roosf6d51ac2015-09-02 13:26:25 -07001367 updateFingerprintListeningState();
Selim Cinek1fcafc42015-07-20 14:39:25 -07001368 }
1369
1370 /**
Adrian Roosb6011622014-05-14 15:52:53 +02001371 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
1372 * @see #sendKeyguardBouncerChanged(boolean)
1373 */
1374 private void handleKeyguardBouncerChanged(int bouncer) {
1375 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
1376 boolean isBouncer = (bouncer == 1);
1377 mBouncer = isBouncer;
1378 for (int i = 0; i < mCallbacks.size(); i++) {
1379 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1380 if (cb != null) {
1381 cb.onKeyguardBouncerChanged(isBouncer);
1382 }
1383 }
Jorim Jaggi3cf7eef2015-09-10 14:36:19 -07001384 updateFingerprintListeningState();
Adrian Roosb6011622014-05-14 15:52:53 +02001385 }
1386
1387 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04001388 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
1389 */
1390 private void handleReportEmergencyCallAction() {
1391 for (int i = 0; i < mCallbacks.size(); i++) {
1392 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1393 if (cb != null) {
1394 cb.onEmergencyCallAction();
1395 }
1396 }
1397 }
1398
Jim Miller16464b82011-10-20 21:10:13 -07001399 private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001400 final boolean nowPluggedIn = current.isPluggedIn();
1401 final boolean wasPluggedIn = old.isPluggedIn();
Jim Miller79a444a2011-02-15 15:02:11 -08001402 final boolean stateChangedWhilePluggedIn =
Jim Miller16464b82011-10-20 21:10:13 -07001403 wasPluggedIn == true && nowPluggedIn == true
1404 && (old.status != current.status);
1405
1406 // change in plug state is always interesting
1407 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001408 return true;
1409 }
1410
1411 // change in battery level while plugged in
Jim Miller16464b82011-10-20 21:10:13 -07001412 if (nowPluggedIn && old.level != current.level) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001413 return true;
1414 }
1415
Jim Miller16464b82011-10-20 21:10:13 -07001416 // change where battery needs charging
Jim Millerbbf1a742012-07-17 18:30:30 -07001417 if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
Jim Miller16464b82011-10-20 21:10:13 -07001418 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001419 }
Adrian Roos76dc5a52015-07-21 16:20:36 -07001420
1421 // change in charging current while plugged in
1422 if (nowPluggedIn && current.maxChargingCurrent != old.maxChargingCurrent) {
1423 return true;
1424 }
1425
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001426 return false;
1427 }
1428
1429 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001430 * Remove the given observer's callback.
1431 *
Jim Miller6212cc02012-09-05 17:35:31 -07001432 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001433 */
Jim Miller6212cc02012-09-05 17:35:31 -07001434 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
1435 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
1436 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1437 if (mCallbacks.get(i).get() == callback) {
1438 mCallbacks.remove(i);
1439 }
1440 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001441 }
1442
1443 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001444 * Register to receive notifications about general keyguard information
1445 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07001446 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001447 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001448 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Jim Miller6212cc02012-09-05 17:35:31 -07001449 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
1450 // Prevent adding duplicate callbacks
1451 for (int i = 0; i < mCallbacks.size(); i++) {
1452 if (mCallbacks.get(i).get() == callback) {
1453 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
1454 new Exception("Called by"));
1455 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07001456 }
1457 }
Jim Miller6212cc02012-09-05 17:35:31 -07001458 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
1459 removeCallback(null); // remove unused references
1460 sendUpdates(callback);
1461 }
1462
1463 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
1464 // Notify listener of the current state
1465 callback.onRefreshBatteryInfo(mBatteryStatus);
1466 callback.onTimeChanged();
1467 callback.onRingerModeChanged(mRingMode);
1468 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05001469 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07001470 callback.onClockVisibilityChanged();
Jim Miller52a61332014-11-12 19:29:51 -08001471 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
1472 final SimData state = data.getValue();
1473 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
1474 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001475 }
1476
Selim Cinek1fcafc42015-07-20 14:39:25 -07001477 public void sendKeyguardReset() {
1478 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
1479 }
1480
Adrian Roosb6011622014-05-14 15:52:53 +02001481 /**
1482 * @see #handleKeyguardBouncerChanged(int)
1483 */
1484 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
1485 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
1486 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
1487 message.arg1 = showingBouncer ? 1 : 0;
1488 message.sendToTarget();
1489 }
1490
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001491 /**
Jim Miller90d5d462011-11-17 16:57:01 -08001492 * 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 -08001493 * have the information earlier than waiting for the intent
1494 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08001495 *
1496 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
1497 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001498 */
Jim Miller52a61332014-11-12 19:29:51 -08001499 public void reportSimUnlocked(int subId) {
1500 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
1501 int slotId = SubscriptionManager.getSlotId(subId);
1502 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001503 }
1504
Brian Colonna7fce3802013-09-17 15:51:32 -04001505 /**
1506 * Report that the emergency call button has been pressed and the emergency dialer is
1507 * about to be displayed.
1508 *
1509 * @param bypassHandler runs immediately.
1510 *
1511 * NOTE: Must be called from UI thread if bypassHandler == true.
1512 */
1513 public void reportEmergencyCallAction(boolean bypassHandler) {
1514 if (!bypassHandler) {
1515 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
1516 } else {
1517 handleReportEmergencyCallAction();
1518 }
1519 }
1520
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001521 /**
1522 * @return Whether the device is provisioned (whether they have gone through
1523 * the setup wizard)
1524 */
1525 public boolean isDeviceProvisioned() {
1526 return mDeviceProvisioned;
1527 }
1528
Jorim Jaggi9f743032015-05-04 15:22:40 -07001529 public void clearFailedUnlockAttempts() {
1530 mFailedAttempts.delete(sCurrentUser);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001531 }
1532
Jorim Jaggi9f743032015-05-04 15:22:40 -07001533 public int getFailedUnlockAttempts() {
1534 return mFailedAttempts.get(sCurrentUser, 0);
1535 }
1536
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001537 public void reportFailedStrongAuthUnlockAttempt() {
Jorim Jaggi9f743032015-05-04 15:22:40 -07001538 mFailedAttempts.put(sCurrentUser, getFailedUnlockAttempts() + 1);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001539 }
1540
Jim Millerf41fc962014-06-18 16:33:51 -07001541 public void clearFingerprintRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07001542 mUserFingerprintAuthenticated.clear();
Jim Millerf41fc962014-06-18 16:33:51 -07001543 }
1544
Jim Miller52a61332014-11-12 19:29:51 -08001545 public boolean isSimPinVoiceSecure() {
1546 // TODO: only count SIMs that handle voice
1547 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07001548 }
1549
1550 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08001551 // True if any SIM is pin secure
1552 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
1553 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
1554 }
1555 return false;
1556 }
1557
Jason Monk9ff69bd2014-12-02 16:43:17 -05001558 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08001559 if (mSimDatas.containsKey(subId)) {
1560 return mSimDatas.get(subId).simState;
1561 } else {
1562 return State.UNKNOWN;
1563 }
1564 }
1565
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001566 /**
1567 * @return true if and only if the state has changed for the specified {@code slotId}
1568 */
1569 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08001570
1571 // This is awful. It exists because there are two APIs for getting the SIM status
1572 // that don't return the complete set of values and have different types. In Keyguard we
1573 // need IccCardConstants, but TelephonyManager would only give us
1574 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08001575 final TelephonyManager tele = TelephonyManager.from(mContext);
1576 int simState = tele.getSimState(slotId);
Jim Miller52a61332014-11-12 19:29:51 -08001577 State state;
1578 try {
xinhe18b9c3c2014-12-02 15:03:20 -08001579 state = State.intToState(simState);
Jim Miller52a61332014-11-12 19:29:51 -08001580 } catch(IllegalArgumentException ex) {
xinhe18b9c3c2014-12-02 15:03:20 -08001581 Log.w(TAG, "Unknown sim state: " + simState);
Jim Miller52a61332014-11-12 19:29:51 -08001582 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05001583 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001584 SimData data = mSimDatas.get(subId);
1585 final boolean changed;
1586 if (data == null) {
1587 data = new SimData(state, slotId, subId);
1588 mSimDatas.put(subId, data);
1589 changed = true; // no data yet; force update
1590 } else {
1591 changed = data.simState != state;
1592 data.simState = state;
1593 }
1594 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07001595 }
1596
1597 public static boolean isSimPinSecure(IccCardConstants.State state) {
1598 final IccCardConstants.State simState = state;
1599 return (simState == IccCardConstants.State.PIN_REQUIRED
1600 || simState == IccCardConstants.State.PUK_REQUIRED
1601 || simState == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07001602 }
Jim Miller8f09fd22013-03-14 19:04:28 -07001603
1604 public DisplayClientState getCachedDisplayClientState() {
1605 return mDisplayClientState;
1606 }
Jim Miller20daffd2013-10-07 14:59:53 -07001607
1608 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
1609 // (KeyguardViewMediator, KeyguardHostView)
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001610 public void dispatchStartedWakingUp() {
1611 synchronized (this) {
1612 mDeviceInteractive = true;
1613 }
1614 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
1615 }
1616
Jorim Jaggi95e40382015-09-16 15:53:42 -07001617 public void dispatchStartedGoingToSleep(int why) {
1618 mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
1619 }
1620
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001621 public void dispatchFinishedGoingToSleep(int why) {
1622 synchronized(this) {
1623 mDeviceInteractive = false;
1624 }
1625 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
1626 }
1627
Jim Miller20daffd2013-10-07 14:59:53 -07001628 public void dispatchScreenTurnedOn() {
1629 synchronized (this) {
1630 mScreenOn = true;
1631 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001632 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
Jim Miller20daffd2013-10-07 14:59:53 -07001633 }
1634
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001635 public void dispatchScreenTurnedOff() {
Jim Miller20daffd2013-10-07 14:59:53 -07001636 synchronized(this) {
1637 mScreenOn = false;
1638 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001639 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
Jim Miller20daffd2013-10-07 14:59:53 -07001640 }
1641
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001642 public boolean isDeviceInteractive() {
1643 return mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -07001644 }
Jim Miller52a61332014-11-12 19:29:51 -08001645
Jorim Jaggi95e40382015-09-16 15:53:42 -07001646 public boolean isGoingToSleep() {
1647 return mGoingToSleep;
1648 }
1649
Jim Miller52a61332014-11-12 19:29:51 -08001650 /**
1651 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
1652 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08001653 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08001654 */
1655 public int getNextSubIdForState(State state) {
1656 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08001657 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08001658 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
1659 for (int i = 0; i < list.size(); i++) {
1660 final SubscriptionInfo info = list.get(i);
1661 final int id = info.getSubscriptionId();
1662 int slotId = SubscriptionManager.getSlotId(id);
1663 if (state == getSimState(id) && bestSlotId > slotId ) {
1664 resultId = id;
1665 bestSlotId = slotId;
1666 }
1667 }
1668 return resultId;
1669 }
1670
1671 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
1672 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
1673 for (int i = 0; i < list.size(); i++) {
1674 SubscriptionInfo info = list.get(i);
1675 if (subId == info.getSubscriptionId()) return info;
1676 }
1677 return null; // not found
1678 }
Jason Monkab525272015-07-13 17:02:49 -04001679
1680 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1681 pw.println("KeyguardUpdateMonitor state:");
1682 pw.println(" SIM States:");
1683 for (SimData data : mSimDatas.values()) {
1684 pw.println(" " + data.toString());
1685 }
1686 pw.println(" Subs:");
1687 if (mSubscriptionInfo != null) {
1688 for (int i = 0; i < mSubscriptionInfo.size(); i++) {
1689 pw.println(" " + mSubscriptionInfo.get(i));
1690 }
1691 }
1692 pw.println(" Service states:");
1693 for (int subId : mServiceStates.keySet()) {
1694 pw.println(" " + subId + "=" + mServiceStates.get(subId));
1695 }
1696 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001697}