blob: a8419bf4cbdfb77f6dafc5a7f428e64036d8b136 [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;
Adrian Roos0c859ae2015-11-23 16:47:50 -080078import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
Jorim Jaggi86bed402015-08-20 18:20:02 -070079import static android.os.BatteryManager.EXTRA_PLUGGED;
80import static android.os.BatteryManager.EXTRA_STATUS;
81
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080082/**
83 * Watches for updates that may be interesting to the keyguard, and provides
84 * the up to date information as well as a registration for callbacks that care
85 * to be updated.
86 *
87 * Note: under time crunch, this has been extended to include some stuff that
88 * doesn't really belong here. see {@link #handleBatteryUpdate} where it shutdowns
Jim Miller258341c2012-08-30 16:50:10 -070089 * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()}
90 * and {@link #clearFailedUnlockAttempts()}. Maybe we should rename this 'KeyguardContext'...
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080091 */
Adrian Roos46842d92014-03-27 14:58:03 +010092public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080093
Jim Millerbbf1a742012-07-17 18:30:30 -070094 private static final String TAG = "KeyguardUpdateMonitor";
Jorim Jaggi5cf17872014-03-26 18:31:48 +010095 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller52a61332014-11-12 19:29:51 -080096 private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
Jim Millerbbf1a742012-07-17 18:30:30 -070097 private static final int LOW_BATTERY_THRESHOLD = 20;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080098
Jorim Jaggie7b12522014-08-06 16:41:21 +020099 private static final String ACTION_FACE_UNLOCK_STARTED
100 = "com.android.facelock.FACE_UNLOCK_STARTED";
101 private static final String ACTION_FACE_UNLOCK_STOPPED
102 = "com.android.facelock.FACE_UNLOCK_STOPPED";
103
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700104 private static final String ACTION_STRONG_AUTH_TIMEOUT =
105 "com.android.systemui.ACTION_STRONG_AUTH_TIMEOUT";
106 private static final String USER_ID = "com.android.systemui.USER_ID";
107
108 private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
109
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700110 /**
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700111 * Milliseconds after unlocking with fingerprint times out, i.e. the user has to use a
112 * strong auth method like password, PIN or pattern.
113 */
114 private static final long FINGERPRINT_UNLOCK_TIMEOUT_MS = 72 * 60 * 60 * 1000;
115
Jim Millerbbf1a742012-07-17 18:30:30 -0700116 // Callback messages
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800117 private static final int MSG_TIME_UPDATE = 301;
118 private static final int MSG_BATTERY_UPDATE = 302;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800119 private static final int MSG_SIM_STATE_CHANGE = 304;
Jim Miller47088bb2009-11-24 00:40:16 -0800120 private static final int MSG_RINGER_MODE_CHANGED = 305;
Jim Millerc23024d2010-02-24 15:37:00 -0800121 private static final int MSG_PHONE_STATE_CHANGED = 306;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700122 private static final int MSG_DEVICE_PROVISIONED = 308;
Jim Miller57375342012-09-09 15:20:31 -0700123 private static final int MSG_DPM_STATE_CHANGED = 309;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500124 private static final int MSG_USER_SWITCHING = 310;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700125 private static final int MSG_KEYGUARD_RESET = 312;
Jim Millerf41fc962014-06-18 16:33:51 -0700126 private static final int MSG_BOOT_COMPLETED = 313;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500127 private static final int MSG_USER_SWITCH_COMPLETE = 314;
Jim Millerf41fc962014-06-18 16:33:51 -0700128 private static final int MSG_USER_INFO_CHANGED = 317;
129 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700130 private static final int MSG_STARTED_WAKING_UP = 319;
131 private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700132 private static final int MSG_STARTED_GOING_TO_SLEEP = 321;
Adrian Roosb6011622014-05-14 15:52:53 +0200133 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700134 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
135 private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
Jason Monk052082c2015-06-11 11:35:23 -0400136 private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
Etan Cohen47051d82015-07-06 16:19:04 -0700137 private static final int MSG_SERVICE_STATE_CHANGE = 330;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700138 private static final int MSG_SCREEN_TURNED_ON = 331;
139 private static final int MSG_SCREEN_TURNED_OFF = 332;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800140
Jorim Jaggi86bed402015-08-20 18:20:02 -0700141 /** Fingerprint state: Not listening to fingerprint. */
142 private static final int FINGERPRINT_STATE_STOPPED = 0;
143
144 /** Fingerprint state: Listening. */
145 private static final int FINGERPRINT_STATE_RUNNING = 1;
146
147 /**
148 * Fingerprint state: Cancelling and waiting for the confirmation from FingerprintService to
149 * send us the confirmation that cancellation has happened.
150 */
151 private static final int FINGERPRINT_STATE_CANCELLING = 2;
152
153 /**
154 * Fingerprint state: During cancelling we got another request to start listening, so when we
155 * receive the cancellation done signal, we should start listening again.
156 */
157 private static final int FINGERPRINT_STATE_CANCELLING_RESTARTING = 3;
158
Adrian Roos0c859ae2015-11-23 16:47:50 -0800159 private static final int DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT = 5000000;
160
Jim Millerdcb3d842012-08-23 19:18:12 -0700161 private static KeyguardUpdateMonitor sInstance;
162
Jim Millerbbf1a742012-07-17 18:30:30 -0700163 private final Context mContext;
Jim Miller52a61332014-11-12 19:29:51 -0800164 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
Etan Cohen47051d82015-07-06 16:19:04 -0700165 HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700166
Jim Millerbbf1a742012-07-17 18:30:30 -0700167 private int mRingMode;
168 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400169 private boolean mKeyguardIsVisible;
Jorim Jaggi71448a72015-08-18 19:49:04 -0700170
171 /**
172 * If true, fingerprint was already authenticated and we don't need to start listening again
173 * until the Keyguard has been dismissed.
174 */
175 private boolean mFingerprintAlreadyAuthenticated;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700176 private boolean mGoingToSleep;
Adrian Roosb6011622014-05-14 15:52:53 +0200177 private boolean mBouncer;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800178 private boolean mBootCompleted;
Jim Millerbbf1a742012-07-17 18:30:30 -0700179
Jim Millerdcb3d842012-08-23 19:18:12 -0700180 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700181 private boolean mDeviceProvisioned;
182
Jim Millerdcb3d842012-08-23 19:18:12 -0700183 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700184 private BatteryStatus mBatteryStatus;
185
Jim Millerdcb3d842012-08-23 19:18:12 -0700186 // Password attempts
Jorim Jaggi9f743032015-05-04 15:22:40 -0700187 private SparseIntArray mFailedAttempts = new SparseIntArray();
Brian Colonnacc4104f2012-10-09 17:50:46 -0400188
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700189 /** Tracks whether strong authentication hasn't been used since quite some time per user. */
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700190 private ArraySet<Integer> mStrongAuthNotTimedOut = new ArraySet<>();
Rakesh Iyera7aa4d62016-01-19 17:27:23 -0800191 private final StrongAuthTracker mStrongAuthTracker;
Jim Millerbbf1a742012-07-17 18:30:30 -0700192
Jim Miller6212cc02012-09-05 17:35:31 -0700193 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700194 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800195 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700196
Brian Colonnaa5239892013-04-15 11:45:40 -0400197 private boolean mSwitchingUser;
198
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700199 private boolean mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -0700200 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800201 private SubscriptionManager mSubscriptionManager;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700202 private AlarmManager mAlarmManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800203 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700204 private TrustManager mTrustManager;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700205 private int mFingerprintRunningState = FINGERPRINT_STATE_STOPPED;
Jim Miller20daffd2013-10-07 14:59:53 -0700206
Jim Millerbbf1a742012-07-17 18:30:30 -0700207 private final Handler mHandler = new Handler() {
208 @Override
209 public void handleMessage(Message msg) {
210 switch (msg.what) {
211 case MSG_TIME_UPDATE:
212 handleTimeUpdate();
213 break;
214 case MSG_BATTERY_UPDATE:
215 handleBatteryUpdate((BatteryStatus) msg.obj);
216 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700217 case MSG_SIM_STATE_CHANGE:
Jim Miller52a61332014-11-12 19:29:51 -0800218 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700219 break;
220 case MSG_RINGER_MODE_CHANGED:
221 handleRingerModeChange(msg.arg1);
222 break;
223 case MSG_PHONE_STATE_CHANGED:
Adrian Roosb6011622014-05-14 15:52:53 +0200224 handlePhoneStateChanged((String) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700225 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700226 case MSG_DEVICE_PROVISIONED:
227 handleDeviceProvisioned();
228 break;
229 case MSG_DPM_STATE_CHANGED:
230 handleDevicePolicyManagerStateChanged();
231 break;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500232 case MSG_USER_SWITCHING:
Adrian Roosb6011622014-05-14 15:52:53 +0200233 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
Chris Wrenf41c61b2012-11-29 15:19:54 -0500234 break;
235 case MSG_USER_SWITCH_COMPLETE:
236 handleUserSwitchComplete(msg.arg1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700237 break;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700238 case MSG_KEYGUARD_RESET:
239 handleKeyguardReset();
240 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200241 case MSG_KEYGUARD_BOUNCER_CHANGED:
242 handleKeyguardBouncerChanged(msg.arg1);
243 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800244 case MSG_BOOT_COMPLETED:
245 handleBootCompleted();
246 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700247 case MSG_USER_INFO_CHANGED:
248 handleUserInfoChanged(msg.arg1);
249 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400250 case MSG_REPORT_EMERGENCY_CALL_ACTION:
251 handleReportEmergencyCallAction();
252 break;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700253 case MSG_STARTED_GOING_TO_SLEEP:
254 handleStartedGoingToSleep(msg.arg1);
255 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700256 case MSG_FINISHED_GOING_TO_SLEEP:
257 handleFinishedGoingToSleep(msg.arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700258 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700259 case MSG_STARTED_WAKING_UP:
260 handleStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -0700261 break;
Jorim Jaggie7b12522014-08-06 16:41:21 +0200262 case MSG_FACE_UNLOCK_STATE_CHANGED:
Adrian Roos4a410172014-08-20 17:41:44 +0200263 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200264 break;
Jim Miller52a61332014-11-12 19:29:51 -0800265 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
266 handleSimSubscriptionInfoChanged();
267 break;
Jason Monk052082c2015-06-11 11:35:23 -0400268 case MSG_AIRPLANE_MODE_CHANGED:
269 handleAirplaneModeChanged();
270 break;
Etan Cohen47051d82015-07-06 16:19:04 -0700271 case MSG_SERVICE_STATE_CHANGE:
272 handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
273 break;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700274 case MSG_SCREEN_TURNED_ON:
275 handleScreenTurnedOn();
276 break;
277 case MSG_SCREEN_TURNED_OFF:
278 handleScreenTurnedOff();
279 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700280 }
281 }
282 };
283
Wink Savilled09c4ca2014-11-22 10:08:16 -0800284 private OnSubscriptionsChangedListener mSubscriptionListener =
285 new OnSubscriptionsChangedListener() {
Jim Miller52a61332014-11-12 19:29:51 -0800286 @Override
Wink Savilled09c4ca2014-11-22 10:08:16 -0800287 public void onSubscriptionsChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800288 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
289 }
290 };
291
Adrian Roos46842d92014-03-27 14:58:03 +0100292 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200293 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Jim Miller9f0753f2015-03-23 23:59:22 -0700294 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200295 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100296
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700297 private static int sCurrentUser;
298
299 public synchronized static void setCurrentUser(int currentUser) {
300 sCurrentUser = currentUser;
301 }
302
303 public synchronized static int getCurrentUser() {
304 return sCurrentUser;
305 }
306
Adrian Roos46842d92014-03-27 14:58:03 +0100307 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700308 public void onTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos46842d92014-03-27 14:58:03 +0100309 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200310 for (int i = 0; i < mCallbacks.size(); i++) {
311 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
312 if (cb != null) {
313 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700314 if (enabled && flags != 0) {
315 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200316 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200317 }
318 }
Adrian Roos46842d92014-03-27 14:58:03 +0100319 }
320
Jim Miller52a61332014-11-12 19:29:51 -0800321 protected void handleSimSubscriptionInfoChanged() {
322 if (DEBUG_SIM_STATES) {
323 Log.v(TAG, "onSubscriptionInfoChanged()");
Wink Savilled09c4ca2014-11-22 10:08:16 -0800324 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
325 if (sil != null) {
326 for (SubscriptionInfo subInfo : sil) {
327 Log.v(TAG, "SubInfo:" + subInfo);
328 }
329 } else {
330 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800331 }
332 }
333 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
334
335 // Hack level over 9000: Because the subscription id is not yet valid when we see the
336 // first update in handleSimStateChange, we need to force refresh all all SIM states
337 // so the subscription id for them is consistent.
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100338 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
Jim Miller52a61332014-11-12 19:29:51 -0800339 for (int i = 0; i < subscriptionInfos.size(); i++) {
340 SubscriptionInfo info = subscriptionInfos.get(i);
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100341 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
342 if (changed) {
343 changedSubscriptions.add(info);
344 }
Jim Miller52a61332014-11-12 19:29:51 -0800345 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100346 for (int i = 0; i < changedSubscriptions.size(); i++) {
347 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800348 for (int j = 0; j < mCallbacks.size(); j++) {
349 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
350 if (cb != null) {
351 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
352 }
353 }
354 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500355 for (int j = 0; j < mCallbacks.size(); j++) {
356 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
357 if (cb != null) {
358 cb.onRefreshCarrierInfo();
359 }
360 }
Jim Miller52a61332014-11-12 19:29:51 -0800361 }
362
Jason Monk052082c2015-06-11 11:35:23 -0400363 private void handleAirplaneModeChanged() {
364 for (int j = 0; j < mCallbacks.size(); j++) {
365 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
366 if (cb != null) {
367 cb.onRefreshCarrierInfo();
368 }
369 }
370 }
371
Wink Savilled09c4ca2014-11-22 10:08:16 -0800372 /** @return List of SubscriptionInfo records, maybe empty but never null */
Jim Miller52a61332014-11-12 19:29:51 -0800373 List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800374 List<SubscriptionInfo> sil = mSubscriptionInfo;
375 if (sil == null || forceReload) {
376 sil = mSubscriptionManager.getActiveSubscriptionInfoList();
377 }
378 if (sil == null) {
379 // getActiveSubscriptionInfoList was null callers expect an empty list.
380 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
381 } else {
382 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800383 }
384 return mSubscriptionInfo;
385 }
386
Adrian Roos7861c662014-07-25 15:37:28 +0200387 @Override
388 public void onTrustManagedChanged(boolean managed, int userId) {
389 mUserTrustIsManaged.put(userId, managed);
390
391 for (int i = 0; i < mCallbacks.size(); i++) {
392 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
393 if (cb != null) {
394 cb.onTrustManagedChanged(userId);
395 }
396 }
397 }
398
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700399 private void onFingerprintAuthenticated(int userId) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700400 mUserFingerprintAuthenticated.put(userId, true);
Jorim Jaggi71448a72015-08-18 19:49:04 -0700401
402 // If fingerprint unlocking is allowed, this event will lead to a Keyguard dismiss or to a
403 // wake-up (if Keyguard is not showing), so we don't need to listen until Keyguard is
404 // fully gone.
405 mFingerprintAlreadyAuthenticated = isUnlockingWithFingerprintAllowed();
Jim Millerf41fc962014-06-18 16:33:51 -0700406 for (int i = 0; i < mCallbacks.size(); i++) {
407 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
408 if (cb != null) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700409 cb.onFingerprintAuthenticated(userId);
Jim Millerf41fc962014-06-18 16:33:51 -0700410 }
411 }
412 }
413
Jim Millerce7eb6d2015-04-03 19:29:13 -0700414 private void handleFingerprintAuthFailed() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700415 for (int i = 0; i < mCallbacks.size(); i++) {
416 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
417 if (cb != null) {
418 cb.onFingerprintAuthFailed();
419 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700420 }
Jim Millerce7eb6d2015-04-03 19:29:13 -0700421 handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized));
422 }
Jim Millerf41fc962014-06-18 16:33:51 -0700423
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700424 private void handleFingerprintAcquired(int acquireInfo) {
425 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
426 return;
427 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700428 for (int i = 0; i < mCallbacks.size(); i++) {
429 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
430 if (cb != null) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700431 cb.onFingerprintAcquired();
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700432 }
433 }
434 }
435
Jim Miller4f364c92015-06-08 19:24:13 -0700436 private void handleFingerprintAuthenticated() {
Jim Millerf41fc962014-06-18 16:33:51 -0700437 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700438 final int userId;
439 try {
440 userId = ActivityManagerNative.getDefault().getCurrentUser().id;
441 } catch (RemoteException e) {
442 Log.e(TAG, "Failed to get current user id: ", e);
443 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700444 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700445 if (isFingerprintDisabled(userId)) {
446 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
447 return;
448 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700449 onFingerprintAuthenticated(userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700450 } finally {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700451 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
Jim Millerf41fc962014-06-18 16:33:51 -0700452 }
453 }
454
Jim Miller9f0753f2015-03-23 23:59:22 -0700455 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700456 for (int i = 0; i < mCallbacks.size(); i++) {
457 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
458 if (cb != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700459 cb.onFingerprintHelp(msgId, helpString);
460 }
461 }
462 }
463
464 private void handleFingerprintError(int msgId, String errString) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700465 if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
466 && mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
467 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
468 startListeningForFingerprint();
469 } else {
470 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
471 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700472 for (int i = 0; i < mCallbacks.size(); i++) {
473 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
474 if (cb != null) {
475 cb.onFingerprintError(msgId, errString);
Jim Millerf41fc962014-06-18 16:33:51 -0700476 }
477 }
478 }
479
Jorim Jaggi3a464782015-08-28 16:59:13 -0700480 private void handleFingerprintLockoutReset() {
481 updateFingerprintListeningState();
482 }
483
Jorim Jaggi86bed402015-08-20 18:20:02 -0700484 private void setFingerprintRunningState(int fingerprintRunningState) {
485 boolean wasRunning = mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
486 boolean isRunning = fingerprintRunningState == FINGERPRINT_STATE_RUNNING;
487 mFingerprintRunningState = fingerprintRunningState;
488
489 // Clients of KeyguardUpdateMonitor don't care about the internal state about the
490 // asynchronousness of the cancel cycle. So only notify them if the actualy running state
491 // has changed.
492 if (wasRunning != isRunning) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700493 notifyFingerprintRunningStateChanged();
494 }
495 }
496
497 private void notifyFingerprintRunningStateChanged() {
498 for (int i = 0; i < mCallbacks.size(); i++) {
499 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
500 if (cb != null) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700501 cb.onFingerprintRunningStateChanged(isFingerprintDetectionRunning());
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700502 }
503 }
504 }
Adrian Roos4a410172014-08-20 17:41:44 +0200505 private void handleFaceUnlockStateChanged(boolean running, int userId) {
506 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200507 for (int i = 0; i < mCallbacks.size(); i++) {
508 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
509 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200510 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200511 }
512 }
513 }
514
Adrian Roos4a410172014-08-20 17:41:44 +0200515 public boolean isFaceUnlockRunning(int userId) {
516 return mUserFaceUnlockRunning.get(userId);
517 }
518
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700519 public boolean isFingerprintDetectionRunning() {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700520 return mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700521 }
522
Jim Miller50e62182014-04-23 17:25:00 -0700523 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100524 // Don't allow trust agent if device is secured with a SIM PIN. This is here
525 // mainly because there's no other way to prompt the user to enter their SIM PIN
526 // once they get past the keyguard screen.
527 final boolean disabledBySimPin = isSimPinSecure();
528 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700529 }
530
Jim Miller06e34502014-07-17 14:46:05 -0700531 private boolean isFingerprintDisabled(int userId) {
532 final DevicePolicyManager dpm =
533 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
534 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
Adrian Roos733b6632015-08-21 14:32:35 -0700535 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0
536 || isSimPinSecure();
Jim Miller06e34502014-07-17 14:46:05 -0700537 }
538
Selim Cineke8bae622015-07-15 13:24:06 -0700539 public boolean getUserCanSkipBouncer(int userId) {
Selim Cinek1fcafc42015-07-20 14:39:25 -0700540 return getUserHasTrust(userId) || (mUserFingerprintAuthenticated.get(userId)
541 && isUnlockingWithFingerprintAllowed());
Selim Cineke8bae622015-07-15 13:24:06 -0700542 }
543
Adrian Roos46842d92014-03-27 14:58:03 +0100544 public boolean getUserHasTrust(int userId) {
Selim Cineke8bae622015-07-15 13:24:06 -0700545 return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100546 }
547
Adrian Roos7861c662014-07-25 15:37:28 +0200548 public boolean getUserTrustIsManaged(int userId) {
549 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
550 }
551
Selim Cinek1fcafc42015-07-20 14:39:25 -0700552 public boolean isUnlockingWithFingerprintAllowed() {
Adrian Roosb5e47222015-08-14 15:53:06 -0700553 return mStrongAuthTracker.isUnlockingWithFingerprintAllowed()
554 && !hasFingerprintUnlockTimedOut(sCurrentUser);
555 }
556
557 public StrongAuthTracker getStrongAuthTracker() {
558 return mStrongAuthTracker;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700559 }
560
561 /**
562 * @return true if the user hasn't use strong authentication (pattern, PIN, password) since a
563 * while and thus can't unlock with fingerprint, false otherwise
564 */
565 public boolean hasFingerprintUnlockTimedOut(int userId) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700566 return !mStrongAuthNotTimedOut.contains(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700567 }
568
569 public void reportSuccessfulStrongAuthUnlockAttempt() {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700570 mStrongAuthNotTimedOut.add(sCurrentUser);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700571 scheduleStrongAuthTimeout();
Jim Millere0507bb2015-08-12 20:30:34 -0700572 if (mFpm != null) {
573 byte[] token = null; /* TODO: pass real auth token once fp HAL supports it */
574 mFpm.resetTimeout(token);
575 }
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700576 }
577
578 private void scheduleStrongAuthTimeout() {
579 long when = SystemClock.elapsedRealtime() + FINGERPRINT_UNLOCK_TIMEOUT_MS;
580 Intent intent = new Intent(ACTION_STRONG_AUTH_TIMEOUT);
581 intent.putExtra(USER_ID, sCurrentUser);
582 PendingIntent sender = PendingIntent.getBroadcast(mContext,
583 sCurrentUser, intent, PendingIntent.FLAG_CANCEL_CURRENT);
584 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, sender);
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700585 notifyStrongAuthStateChanged(sCurrentUser);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700586 }
587
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700588 private void notifyStrongAuthStateChanged(int userId) {
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700589 for (int i = 0; i < mCallbacks.size(); i++) {
590 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
591 if (cb != null) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700592 cb.onStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700593 }
594 }
Selim Cinek1fcafc42015-07-20 14:39:25 -0700595 }
596
Jim Miller8f09fd22013-03-14 19:04:28 -0700597 static class DisplayClientState {
598 public int clientGeneration;
599 public boolean clearing;
600 public PendingIntent intent;
601 public int playbackState;
602 public long playbackEventTime;
603 }
604
605 private DisplayClientState mDisplayClientState = new DisplayClientState();
606
Jim Millerbbf1a742012-07-17 18:30:30 -0700607 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
608
Jim Millerd72d5ac2015-09-29 18:55:32 -0700609 @Override
Jim Millerbbf1a742012-07-17 18:30:30 -0700610 public void onReceive(Context context, Intent intent) {
611 final String action = intent.getAction();
612 if (DEBUG) Log.d(TAG, "received broadcast " + action);
613
614 if (Intent.ACTION_TIME_TICK.equals(action)
615 || Intent.ACTION_TIME_CHANGED.equals(action)
Adrian Roos48c796c2014-09-01 14:59:23 +0200616 || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700617 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Jim Millerbbf1a742012-07-17 18:30:30 -0700618 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
619 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
620 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
621 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
622 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
Adrian Roos0c859ae2015-11-23 16:47:50 -0800623
624 final int maxChargingMicroAmp = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
625 int maxChargingMicroVolt = intent.getIntExtra(EXTRA_MAX_CHARGING_VOLTAGE, -1);
626 final int maxChargingMicroWatt;
627
628 if (maxChargingMicroVolt <= 0) {
629 maxChargingMicroVolt = DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT;
630 }
631 if (maxChargingMicroAmp > 0) {
632 // Calculating muW = muA * muV / (10^6 mu^2 / mu); splitting up the divisor
633 // to maintain precision equally on both factors.
634 maxChargingMicroWatt = (maxChargingMicroAmp / 1000)
635 * (maxChargingMicroVolt / 1000);
636 } else {
637 maxChargingMicroWatt = -1;
638 }
Jim Millerbbf1a742012-07-17 18:30:30 -0700639 final Message msg = mHandler.obtainMessage(
Adrian Roos7b043112015-07-10 13:00:33 -0700640 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
Adrian Roos0c859ae2015-11-23 16:47:50 -0800641 maxChargingMicroWatt));
Jim Millerbbf1a742012-07-17 18:30:30 -0700642 mHandler.sendMessage(msg);
643 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Jim Miller52a61332014-11-12 19:29:51 -0800644 SimData args = SimData.fromIntent(intent);
Jim Millerbbf1a742012-07-17 18:30:30 -0700645 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -0800646 Log.v(TAG, "action " + action
647 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
648 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -0700649 }
Jim Miller52a61332014-11-12 19:29:51 -0800650 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
651 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -0700652 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
653 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
654 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
655 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
656 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
657 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Jason Monk052082c2015-06-11 11:35:23 -0400658 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
659 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800660 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700661 dispatchBootCompleted();
Etan Cohen47051d82015-07-06 16:19:04 -0700662 } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
663 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
664 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
665 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
666 if (DEBUG) {
667 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
668 + subId);
669 }
670 mHandler.sendMessage(
671 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
Jim Millerbbf1a742012-07-17 18:30:30 -0700672 }
673 }
674 };
Jim Miller2de5ee82012-06-14 22:22:50 -0700675
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700676 private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
677
Jim Millerd72d5ac2015-09-29 18:55:32 -0700678 @Override
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700679 public void onReceive(Context context, Intent intent) {
680 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +0200681 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
682 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
683 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700684 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
685 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +0200686 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
687 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
688 getSendingUserId()));
689 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
690 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
691 getSendingUserId()));
692 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
693 .equals(action)) {
694 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700695 }
696 }
697 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700698
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700699 private final BroadcastReceiver mStrongAuthTimeoutReceiver = new BroadcastReceiver() {
700 @Override
701 public void onReceive(Context context, Intent intent) {
702 if (ACTION_STRONG_AUTH_TIMEOUT.equals(intent.getAction())) {
703 int userId = intent.getIntExtra(USER_ID, -1);
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700704 mStrongAuthNotTimedOut.remove(userId);
705 notifyStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700706 }
707 }
708 };
709
Jorim Jaggi3a464782015-08-28 16:59:13 -0700710 private final FingerprintManager.LockoutResetCallback mLockoutResetCallback
711 = new FingerprintManager.LockoutResetCallback() {
712 @Override
713 public void onLockoutReset() {
714 handleFingerprintLockoutReset();
715 }
716 };
717
Jim Miller9f0753f2015-03-23 23:59:22 -0700718 private FingerprintManager.AuthenticationCallback mAuthenticationCallback
719 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -0700720
721 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -0700722 public void onAuthenticationFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700723 handleFingerprintAuthFailed();
Jim Millerce7eb6d2015-04-03 19:29:13 -0700724 };
725
726 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700727 public void onAuthenticationSucceeded(AuthenticationResult result) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700728 handleFingerprintAuthenticated();
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() {
Jorim Jaggi864e64b2015-05-20 14:13:23 -0700903 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -0700904 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.onStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -0700909 }
910 }
911 }
912
Jorim Jaggi95e40382015-09-16 15:53:42 -0700913 protected void handleStartedGoingToSleep(int arg1) {
Jim Millerf41fc962014-06-18 16:33:51 -0700914 clearFingerprintRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -0700915 final int count = mCallbacks.size();
916 for (int i = 0; i < count; i++) {
917 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
918 if (cb != null) {
Jorim Jaggi95e40382015-09-16 15:53:42 -0700919 cb.onStartedGoingToSleep(arg1);
920 }
921 }
922 mGoingToSleep = true;
923 mFingerprintAlreadyAuthenticated = false;
924 updateFingerprintListeningState();
925 }
926
927 protected void handleFinishedGoingToSleep(int arg1) {
928 mGoingToSleep = false;
929 final int count = mCallbacks.size();
930 for (int i = 0; i < count; i++) {
931 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
932 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700933 cb.onFinishedGoingToSleep(arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700934 }
935 }
Jorim Jaggiea657062015-04-28 13:45:11 -0700936 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -0700937 }
938
Jorim Jaggif1518da2015-07-30 11:56:36 -0700939 private void handleScreenTurnedOn() {
940 final int count = mCallbacks.size();
941 for (int i = 0; i < count; i++) {
942 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
943 if (cb != null) {
944 cb.onScreenTurnedOn();
945 }
946 }
947 }
948
949 private void handleScreenTurnedOff() {
950 final int count = mCallbacks.size();
951 for (int i = 0; i < count; i++) {
952 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
953 if (cb != null) {
954 cb.onScreenTurnedOff();
955 }
956 }
957 }
958
Adam Powell43a372f2013-09-27 17:43:53 -0700959 /**
960 * IMPORTANT: Must be called from UI thread.
961 */
962 public void dispatchSetBackground(Bitmap bmp) {
963 if (DEBUG) Log.d(TAG, "dispatchSetBackground");
964 final int count = mCallbacks.size();
965 for (int i = 0; i < count; i++) {
966 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
967 if (cb != null) {
968 cb.onSetBackground(bmp);
969 }
970 }
971 }
972
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700973 private void handleUserInfoChanged(int userId) {
974 for (int i = 0; i < mCallbacks.size(); i++) {
975 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
976 if (cb != null) {
977 cb.onUserInfoChanged(userId);
978 }
979 }
980 }
981
Jim Millerdcb3d842012-08-23 19:18:12 -0700982 private KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800983 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800984 mSubscriptionManager = SubscriptionManager.from(context);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700985 mAlarmManager = context.getSystemService(AlarmManager.class);
Michael Jurkafff56142012-11-28 16:51:00 -0800986 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Rakesh Iyera7aa4d62016-01-19 17:27:23 -0800987 mStrongAuthTracker = new StrongAuthTracker(context);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700988
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800989 // Since device can't be un-provisioned, we only need to register a content observer
990 // to update mDeviceProvisioned when we are...
991 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700992 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800993 }
Jim Miller47088bb2009-11-24 00:40:16 -0800994
Jim Millerbbf1a742012-07-17 18:30:30 -0700995 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Adrian Roos7b043112015-07-10 13:00:33 -0700996 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800997
Jim Millerbbf1a742012-07-17 18:30:30 -0700998 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800999 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001000 filter.addAction(Intent.ACTION_TIME_TICK);
1001 filter.addAction(Intent.ACTION_TIME_CHANGED);
1002 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
1003 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Jason Monk052082c2015-06-11 11:35:23 -04001004 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001005 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Etan Cohen47051d82015-07-06 16:19:04 -07001006 filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -08001007 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -08001008 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Jim Millerbbf1a742012-07-17 18:30:30 -07001009 context.registerReceiver(mBroadcastReceiver, filter);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001010
Adam Cohenc276e822012-11-08 13:01:08 -08001011 final IntentFilter bootCompleteFilter = new IntentFilter();
1012 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1013 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
1014 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter);
1015
Adrian Roos48c796c2014-09-01 14:59:23 +02001016 final IntentFilter allUserFilter = new IntentFilter();
1017 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
1018 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
1019 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
1020 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
1021 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1022 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001023 null, null);
1024
Wink Saville071743f2015-01-12 17:11:04 -08001025 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001026 try {
1027 ActivityManagerNative.getDefault().registerUserSwitchObserver(
1028 new IUserSwitchObserver.Stub() {
1029 @Override
1030 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001031 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001032 newUserId, 0, reply));
1033 }
1034 @Override
1035 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001036 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +02001037 newUserId, 0));
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001038 }
Kenny Guy42979622015-04-13 18:03:05 +00001039 @Override
1040 public void onForegroundProfileSwitch(int newProfileId) {
1041 // Ignore.
1042 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001043 });
1044 } catch (RemoteException e) {
1045 // TODO Auto-generated catch block
1046 e.printStackTrace();
1047 }
Adrian Roos46842d92014-03-27 14:58:03 +01001048
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001049 IntentFilter strongAuthTimeoutFilter = new IntentFilter();
1050 strongAuthTimeoutFilter.addAction(ACTION_STRONG_AUTH_TIMEOUT);
1051 context.registerReceiver(mStrongAuthTimeoutReceiver, strongAuthTimeoutFilter,
1052 PERMISSION_SELF, null /* handler */);
Jorim Jaggi237b0612015-05-01 14:28:49 -07001053 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
1054 mTrustManager.registerTrustListener(this);
Adrian Roosb5e47222015-08-14 15:53:06 -07001055 new LockPatternUtils(context).registerStrongAuthTracker(mStrongAuthTracker);
Jim Millerf41fc962014-06-18 16:33:51 -07001056
Jim Miller9f0753f2015-03-23 23:59:22 -07001057 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
Jorim Jaggiea657062015-04-28 13:45:11 -07001058 updateFingerprintListeningState();
Jorim Jaggi3a464782015-08-28 16:59:13 -07001059 if (mFpm != null) {
1060 mFpm.addLockoutResetCallback(mLockoutResetCallback);
1061 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001062 }
1063
1064 private void updateFingerprintListeningState() {
1065 boolean shouldListenForFingerprint = shouldListenForFingerprint();
Jorim Jaggi86bed402015-08-20 18:20:02 -07001066 if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING && !shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001067 stopListeningForFingerprint();
Jorim Jaggi86bed402015-08-20 18:20:02 -07001068 } else if (mFingerprintRunningState != FINGERPRINT_STATE_RUNNING
1069 && shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001070 startListeningForFingerprint();
1071 }
1072 }
1073
1074 private boolean shouldListenForFingerprint() {
Jorim Jaggi95e40382015-09-16 15:53:42 -07001075 return (mKeyguardIsVisible || !mDeviceInteractive || mBouncer || mGoingToSleep)
1076 && !mSwitchingUser && !mFingerprintAlreadyAuthenticated
1077 && !isFingerprintDisabled(getCurrentUser());
Jim Miller9f0753f2015-03-23 23:59:22 -07001078 }
1079
Jim Millerce7eb6d2015-04-03 19:29:13 -07001080 private void startListeningForFingerprint() {
Jorim Jaggi86bed402015-08-20 18:20:02 -07001081 if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING) {
1082 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING_RESTARTING);
1083 return;
1084 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001085 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -07001086 int userId = ActivityManager.getCurrentUser();
Jorim Jaggi71448a72015-08-18 19:49:04 -07001087 if (isUnlockWithFingerprintPossible(userId)) {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001088 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001089 mFingerprintCancelSignal.cancel();
1090 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001091 mFingerprintCancelSignal = new CancellationSignal();
Jim Millerf501b582015-06-03 16:36:31 -07001092 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null, userId);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001093 setFingerprintRunningState(FINGERPRINT_STATE_RUNNING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001094 }
1095 }
1096
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001097 public boolean isUnlockWithFingerprintPossible(int userId) {
Selim Cinek3122fa82015-06-18 01:38:59 -07001098 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
1099 && mFpm.getEnrolledFingerprints(userId).size() > 0;
1100 }
1101
Jorim Jaggiea657062015-04-28 13:45:11 -07001102 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001103 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
Jorim Jaggi86bed402015-08-20 18:20:02 -07001104 if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001105 mFingerprintCancelSignal.cancel();
Jim Millerce7eb6d2015-04-03 19:29:13 -07001106 mFingerprintCancelSignal = null;
Jorim Jaggi86bed402015-08-20 18:20:02 -07001107 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001108 }
Jorim Jaggi86bed402015-08-20 18:20:02 -07001109 if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
1110 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
1111 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001112 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001113
Michael Jurkafff56142012-11-28 16:51:00 -08001114 private boolean isDeviceProvisionedInSettingsDb() {
1115 return Settings.Global.getInt(mContext.getContentResolver(),
1116 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1117 }
1118
Jim Millerbbf1a742012-07-17 18:30:30 -07001119 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -08001120 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001121 @Override
1122 public void onChange(boolean selfChange) {
1123 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -08001124 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001125 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001126 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001127 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001128 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001129 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001130 };
1131
1132 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -07001133 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -08001134 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -07001135
1136 // prevent a race condition between where we check the flag and where we register the
1137 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -08001138 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001139 if (provisioned != mDeviceProvisioned) {
1140 mDeviceProvisioned = provisioned;
1141 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001142 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001143 }
1144 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001145 }
1146
Jim Millerbbf1a742012-07-17 18:30:30 -07001147 /**
1148 * Handle {@link #MSG_DPM_STATE_CHANGED}
1149 */
Jim Millerb0304762012-03-13 20:01:25 -07001150 protected void handleDevicePolicyManagerStateChanged() {
Adrian Roos733b6632015-08-21 14:32:35 -07001151 updateFingerprintListeningState();
Jim Millerdcb3d842012-08-23 19:18:12 -07001152 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1153 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1154 if (cb != null) {
1155 cb.onDevicePolicyManagerStateChanged();
1156 }
Jim Millerb0304762012-03-13 20:01:25 -07001157 }
1158 }
1159
Jim Millerbbf1a742012-07-17 18:30:30 -07001160 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001161 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -07001162 */
Chris Wrenf41c61b2012-11-29 15:19:54 -05001163 protected void handleUserSwitching(int userId, IRemoteCallback reply) {
Jorim Jaggiaa4d32a2015-05-13 16:30:04 -07001164 mSwitchingUser = true;
1165 updateFingerprintListeningState();
1166
Jim Millerbbf1a742012-07-17 18:30:30 -07001167 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001168 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1169 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001170 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -07001171 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001172 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001173 try {
1174 reply.sendResult(null);
1175 } catch (RemoteException e) {
1176 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001177 }
1178
Jim Millerbbf1a742012-07-17 18:30:30 -07001179 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001180 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
1181 */
1182 protected void handleUserSwitchComplete(int userId) {
Jorim Jaggiaa4d32a2015-05-13 16:30:04 -07001183 mSwitchingUser = false;
1184 updateFingerprintListeningState();
1185
Chris Wrenf41c61b2012-11-29 15:19:54 -05001186 for (int i = 0; i < mCallbacks.size(); i++) {
1187 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1188 if (cb != null) {
1189 cb.onUserSwitchComplete(userId);
1190 }
1191 }
1192 }
1193
1194 /**
Jim Miller90873d52013-09-26 18:11:38 -07001195 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
1196 * keyguard crashes sometime after boot, then it will never receive this
1197 * broadcast and hence not handle the event. This method is ultimately called by
1198 * PhoneWindowManager in this case.
1199 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001200 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001201 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -07001202 }
1203
1204 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001205 * Handle {@link #MSG_BOOT_COMPLETED}
1206 */
1207 protected void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001208 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001209 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001210 for (int i = 0; i < mCallbacks.size(); i++) {
1211 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1212 if (cb != null) {
1213 cb.onBootCompleted();
1214 }
1215 }
1216 }
1217
1218 /**
Jim Miller5ecd8112013-01-09 18:50:26 -08001219 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001220 * destroyed.
1221 */
1222 public boolean hasBootCompleted() {
1223 return mBootCompleted;
1224 }
1225
1226 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001227 * Handle {@link #MSG_DEVICE_PROVISIONED}
1228 */
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001229 protected void handleDeviceProvisioned() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001230 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001231 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1232 if (cb != null) {
1233 cb.onDeviceProvisioned();
1234 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001235 }
Michael Jurkafff56142012-11-28 16:51:00 -08001236 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001237 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -08001238 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
1239 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001240 }
1241 }
1242
Jim Millerbbf1a742012-07-17 18:30:30 -07001243 /**
1244 * Handle {@link #MSG_PHONE_STATE_CHANGED}
1245 */
Jim Millerc23024d2010-02-24 15:37:00 -08001246 protected void handlePhoneStateChanged(String newState) {
1247 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001248 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
1249 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
1250 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
1251 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
1252 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
1253 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
1254 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001255 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001256 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1257 if (cb != null) {
1258 cb.onPhoneStateChanged(mPhoneState);
1259 }
Jim Millerc23024d2010-02-24 15:37:00 -08001260 }
1261 }
1262
Jim Millerbbf1a742012-07-17 18:30:30 -07001263 /**
1264 * Handle {@link #MSG_RINGER_MODE_CHANGED}
1265 */
Jim Miller47088bb2009-11-24 00:40:16 -08001266 protected void handleRingerModeChange(int mode) {
1267 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001268 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -07001269 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001270 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1271 if (cb != null) {
1272 cb.onRingerModeChanged(mode);
1273 }
Jim Miller47088bb2009-11-24 00:40:16 -08001274 }
1275 }
1276
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001277 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001278 * Handle {@link #MSG_TIME_UPDATE}
1279 */
1280 private void handleTimeUpdate() {
1281 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001282 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001283 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1284 if (cb != null) {
1285 cb.onTimeChanged();
1286 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001287 }
1288 }
1289
1290 /**
1291 * Handle {@link #MSG_BATTERY_UPDATE}
1292 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001293 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001294 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001295 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
1296 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07001297 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001298 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001299 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1300 if (cb != null) {
1301 cb.onRefreshBatteryInfo(status);
1302 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001303 }
1304 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001305 }
1306
1307 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001308 * Handle {@link #MSG_SIM_STATE_CHANGE}
1309 */
Jim Miller52a61332014-11-12 19:29:51 -08001310 private void handleSimStateChange(int subId, int slotId, State state) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001311
Jim Miller52a61332014-11-12 19:29:51 -08001312 if (DEBUG_SIM_STATES) {
1313 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
1314 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001315 }
1316
Wink Savillea54bf652014-12-11 13:37:50 -08001317 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08001318 Log.w(TAG, "invalid subId in handleSimStateChange()");
1319 return;
1320 }
1321
1322 SimData data = mSimDatas.get(subId);
1323 final boolean changed;
1324 if (data == null) {
1325 data = new SimData(state, slotId, subId);
1326 mSimDatas.put(subId, data);
1327 changed = true; // no data yet; force update
1328 } else {
1329 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
1330 data.simState = state;
1331 data.subId = subId;
1332 data.slotId = slotId;
1333 }
1334 if (changed && state != State.UNKNOWN) {
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) {
Jim Miller52a61332014-11-12 19:29:51 -08001338 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07001339 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001340 }
1341 }
1342 }
1343
Jim Millerbbf1a742012-07-17 18:30:30 -07001344 /**
Etan Cohen47051d82015-07-06 16:19:04 -07001345 * Handle {@link #MSG_SERVICE_STATE_CHANGE}
1346 */
1347 private void handleServiceStateChange(int subId, ServiceState serviceState) {
1348 if (DEBUG) {
1349 Log.d(TAG,
1350 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
1351 }
1352
1353 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1354 Log.w(TAG, "invalid subId in handleServiceStateChange()");
1355 return;
1356 }
1357
1358 mServiceStates.put(subId, serviceState);
1359
1360 for (int j = 0; j < mCallbacks.size(); j++) {
1361 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
1362 if (cb != null) {
1363 cb.onRefreshCarrierInfo();
1364 }
1365 }
1366 }
1367
1368 /**
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001369 * Notifies that the visibility state of Keyguard has changed.
1370 *
1371 * <p>Needs to be called from the main thread.
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001372 */
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001373 public void onKeyguardVisibilityChanged(boolean showing) {
1374 if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
1375 mKeyguardIsVisible = showing;
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001376 for (int i = 0; i < mCallbacks.size(); i++) {
1377 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1378 if (cb != null) {
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001379 cb.onKeyguardVisibilityChangedRaw(showing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001380 }
1381 }
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001382 if (!showing) {
Jorim Jaggi71448a72015-08-18 19:49:04 -07001383 mFingerprintAlreadyAuthenticated = false;
1384 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001385 updateFingerprintListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001386 }
1387
Brian Colonna7fce3802013-09-17 15:51:32 -04001388 /**
Selim Cinek1fcafc42015-07-20 14:39:25 -07001389 * Handle {@link #MSG_KEYGUARD_RESET}
1390 */
1391 private void handleKeyguardReset() {
1392 if (DEBUG) Log.d(TAG, "handleKeyguardReset");
Adrian Roosf6d51ac2015-09-02 13:26:25 -07001393 updateFingerprintListeningState();
Selim Cinek1fcafc42015-07-20 14:39:25 -07001394 }
1395
1396 /**
Adrian Roosb6011622014-05-14 15:52:53 +02001397 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
1398 * @see #sendKeyguardBouncerChanged(boolean)
1399 */
1400 private void handleKeyguardBouncerChanged(int bouncer) {
1401 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
1402 boolean isBouncer = (bouncer == 1);
1403 mBouncer = isBouncer;
1404 for (int i = 0; i < mCallbacks.size(); i++) {
1405 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1406 if (cb != null) {
1407 cb.onKeyguardBouncerChanged(isBouncer);
1408 }
1409 }
Jorim Jaggi3cf7eef2015-09-10 14:36:19 -07001410 updateFingerprintListeningState();
Adrian Roosb6011622014-05-14 15:52:53 +02001411 }
1412
1413 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04001414 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
1415 */
1416 private void handleReportEmergencyCallAction() {
1417 for (int i = 0; i < mCallbacks.size(); i++) {
1418 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1419 if (cb != null) {
1420 cb.onEmergencyCallAction();
1421 }
1422 }
1423 }
1424
Jim Miller16464b82011-10-20 21:10:13 -07001425 private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001426 final boolean nowPluggedIn = current.isPluggedIn();
1427 final boolean wasPluggedIn = old.isPluggedIn();
Jim Miller79a444a2011-02-15 15:02:11 -08001428 final boolean stateChangedWhilePluggedIn =
Jim Miller16464b82011-10-20 21:10:13 -07001429 wasPluggedIn == true && nowPluggedIn == true
1430 && (old.status != current.status);
1431
1432 // change in plug state is always interesting
1433 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001434 return true;
1435 }
1436
1437 // change in battery level while plugged in
Jim Miller16464b82011-10-20 21:10:13 -07001438 if (nowPluggedIn && old.level != current.level) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001439 return true;
1440 }
1441
Jim Miller16464b82011-10-20 21:10:13 -07001442 // change where battery needs charging
Jim Millerbbf1a742012-07-17 18:30:30 -07001443 if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
Jim Miller16464b82011-10-20 21:10:13 -07001444 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001445 }
Adrian Roos76dc5a52015-07-21 16:20:36 -07001446
1447 // change in charging current while plugged in
Adrian Roos0c859ae2015-11-23 16:47:50 -08001448 if (nowPluggedIn && current.maxChargingWattage != old.maxChargingWattage) {
Adrian Roos76dc5a52015-07-21 16:20:36 -07001449 return true;
1450 }
1451
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001452 return false;
1453 }
1454
1455 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001456 * Remove the given observer's callback.
1457 *
Jim Miller6212cc02012-09-05 17:35:31 -07001458 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001459 */
Jim Miller6212cc02012-09-05 17:35:31 -07001460 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
1461 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
1462 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1463 if (mCallbacks.get(i).get() == callback) {
1464 mCallbacks.remove(i);
1465 }
1466 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001467 }
1468
1469 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001470 * Register to receive notifications about general keyguard information
1471 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07001472 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001473 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001474 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Jim Miller6212cc02012-09-05 17:35:31 -07001475 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
1476 // Prevent adding duplicate callbacks
1477 for (int i = 0; i < mCallbacks.size(); i++) {
1478 if (mCallbacks.get(i).get() == callback) {
1479 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
1480 new Exception("Called by"));
1481 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07001482 }
1483 }
Jim Miller6212cc02012-09-05 17:35:31 -07001484 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
1485 removeCallback(null); // remove unused references
1486 sendUpdates(callback);
1487 }
1488
1489 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
1490 // Notify listener of the current state
1491 callback.onRefreshBatteryInfo(mBatteryStatus);
1492 callback.onTimeChanged();
1493 callback.onRingerModeChanged(mRingMode);
1494 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05001495 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07001496 callback.onClockVisibilityChanged();
Jim Miller52a61332014-11-12 19:29:51 -08001497 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
1498 final SimData state = data.getValue();
1499 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
1500 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001501 }
1502
Selim Cinek1fcafc42015-07-20 14:39:25 -07001503 public void sendKeyguardReset() {
1504 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
1505 }
1506
Adrian Roosb6011622014-05-14 15:52:53 +02001507 /**
1508 * @see #handleKeyguardBouncerChanged(int)
1509 */
1510 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
1511 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
1512 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
1513 message.arg1 = showingBouncer ? 1 : 0;
1514 message.sendToTarget();
1515 }
1516
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001517 /**
Jim Miller90d5d462011-11-17 16:57:01 -08001518 * 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 -08001519 * have the information earlier than waiting for the intent
1520 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08001521 *
1522 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
1523 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001524 */
Jim Miller52a61332014-11-12 19:29:51 -08001525 public void reportSimUnlocked(int subId) {
1526 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
1527 int slotId = SubscriptionManager.getSlotId(subId);
1528 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001529 }
1530
Brian Colonna7fce3802013-09-17 15:51:32 -04001531 /**
1532 * Report that the emergency call button has been pressed and the emergency dialer is
1533 * about to be displayed.
1534 *
1535 * @param bypassHandler runs immediately.
1536 *
1537 * NOTE: Must be called from UI thread if bypassHandler == true.
1538 */
1539 public void reportEmergencyCallAction(boolean bypassHandler) {
1540 if (!bypassHandler) {
1541 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
1542 } else {
1543 handleReportEmergencyCallAction();
1544 }
1545 }
1546
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001547 /**
1548 * @return Whether the device is provisioned (whether they have gone through
1549 * the setup wizard)
1550 */
1551 public boolean isDeviceProvisioned() {
1552 return mDeviceProvisioned;
1553 }
1554
Jorim Jaggi9f743032015-05-04 15:22:40 -07001555 public void clearFailedUnlockAttempts() {
1556 mFailedAttempts.delete(sCurrentUser);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001557 }
1558
Xiyuan Xiace64cea2016-01-06 08:51:16 -08001559 public int getFailedUnlockAttempts(int userId) {
1560 return mFailedAttempts.get(userId, 0);
Jorim Jaggi9f743032015-05-04 15:22:40 -07001561 }
1562
Xiyuan Xiace64cea2016-01-06 08:51:16 -08001563 public void reportFailedStrongAuthUnlockAttempt(int userId) {
1564 mFailedAttempts.put(userId, getFailedUnlockAttempts(userId) + 1);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001565 }
1566
Jim Millerf41fc962014-06-18 16:33:51 -07001567 public void clearFingerprintRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07001568 mUserFingerprintAuthenticated.clear();
Jim Millerf41fc962014-06-18 16:33:51 -07001569 }
1570
Jim Miller52a61332014-11-12 19:29:51 -08001571 public boolean isSimPinVoiceSecure() {
1572 // TODO: only count SIMs that handle voice
1573 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07001574 }
1575
1576 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08001577 // True if any SIM is pin secure
1578 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
1579 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
1580 }
1581 return false;
1582 }
1583
Jason Monk9ff69bd2014-12-02 16:43:17 -05001584 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08001585 if (mSimDatas.containsKey(subId)) {
1586 return mSimDatas.get(subId).simState;
1587 } else {
1588 return State.UNKNOWN;
1589 }
1590 }
1591
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001592 /**
1593 * @return true if and only if the state has changed for the specified {@code slotId}
1594 */
1595 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08001596
1597 // This is awful. It exists because there are two APIs for getting the SIM status
1598 // that don't return the complete set of values and have different types. In Keyguard we
1599 // need IccCardConstants, but TelephonyManager would only give us
1600 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08001601 final TelephonyManager tele = TelephonyManager.from(mContext);
1602 int simState = tele.getSimState(slotId);
Jim Miller52a61332014-11-12 19:29:51 -08001603 State state;
1604 try {
xinhe18b9c3c2014-12-02 15:03:20 -08001605 state = State.intToState(simState);
Jim Miller52a61332014-11-12 19:29:51 -08001606 } catch(IllegalArgumentException ex) {
xinhe18b9c3c2014-12-02 15:03:20 -08001607 Log.w(TAG, "Unknown sim state: " + simState);
Jim Miller52a61332014-11-12 19:29:51 -08001608 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05001609 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001610 SimData data = mSimDatas.get(subId);
1611 final boolean changed;
1612 if (data == null) {
1613 data = new SimData(state, slotId, subId);
1614 mSimDatas.put(subId, data);
1615 changed = true; // no data yet; force update
1616 } else {
1617 changed = data.simState != state;
1618 data.simState = state;
1619 }
1620 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07001621 }
1622
1623 public static boolean isSimPinSecure(IccCardConstants.State state) {
1624 final IccCardConstants.State simState = state;
1625 return (simState == IccCardConstants.State.PIN_REQUIRED
1626 || simState == IccCardConstants.State.PUK_REQUIRED
1627 || simState == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07001628 }
Jim Miller8f09fd22013-03-14 19:04:28 -07001629
1630 public DisplayClientState getCachedDisplayClientState() {
1631 return mDisplayClientState;
1632 }
Jim Miller20daffd2013-10-07 14:59:53 -07001633
1634 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
1635 // (KeyguardViewMediator, KeyguardHostView)
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001636 public void dispatchStartedWakingUp() {
1637 synchronized (this) {
1638 mDeviceInteractive = true;
1639 }
1640 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
1641 }
1642
Jorim Jaggi95e40382015-09-16 15:53:42 -07001643 public void dispatchStartedGoingToSleep(int why) {
1644 mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
1645 }
1646
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001647 public void dispatchFinishedGoingToSleep(int why) {
1648 synchronized(this) {
1649 mDeviceInteractive = false;
1650 }
1651 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
1652 }
1653
Jim Miller20daffd2013-10-07 14:59:53 -07001654 public void dispatchScreenTurnedOn() {
1655 synchronized (this) {
1656 mScreenOn = true;
1657 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001658 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
Jim Miller20daffd2013-10-07 14:59:53 -07001659 }
1660
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001661 public void dispatchScreenTurnedOff() {
Jim Miller20daffd2013-10-07 14:59:53 -07001662 synchronized(this) {
1663 mScreenOn = false;
1664 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001665 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
Jim Miller20daffd2013-10-07 14:59:53 -07001666 }
1667
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001668 public boolean isDeviceInteractive() {
1669 return mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -07001670 }
Jim Miller52a61332014-11-12 19:29:51 -08001671
Jorim Jaggi95e40382015-09-16 15:53:42 -07001672 public boolean isGoingToSleep() {
1673 return mGoingToSleep;
1674 }
1675
Jim Miller52a61332014-11-12 19:29:51 -08001676 /**
1677 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
1678 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08001679 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08001680 */
1681 public int getNextSubIdForState(State state) {
1682 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08001683 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08001684 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
1685 for (int i = 0; i < list.size(); i++) {
1686 final SubscriptionInfo info = list.get(i);
1687 final int id = info.getSubscriptionId();
1688 int slotId = SubscriptionManager.getSlotId(id);
1689 if (state == getSimState(id) && bestSlotId > slotId ) {
1690 resultId = id;
1691 bestSlotId = slotId;
1692 }
1693 }
1694 return resultId;
1695 }
1696
1697 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
1698 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
1699 for (int i = 0; i < list.size(); i++) {
1700 SubscriptionInfo info = list.get(i);
1701 if (subId == info.getSubscriptionId()) return info;
1702 }
1703 return null; // not found
1704 }
Jason Monkab525272015-07-13 17:02:49 -04001705
1706 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1707 pw.println("KeyguardUpdateMonitor state:");
1708 pw.println(" SIM States:");
1709 for (SimData data : mSimDatas.values()) {
1710 pw.println(" " + data.toString());
1711 }
1712 pw.println(" Subs:");
1713 if (mSubscriptionInfo != null) {
1714 for (int i = 0; i < mSubscriptionInfo.size(); i++) {
1715 pw.println(" " + mSubscriptionInfo.get(i));
1716 }
1717 }
1718 pw.println(" Service states:");
1719 for (int subId : mServiceStates.keySet()) {
1720 pw.println(" " + subId + "=" + mServiceStates.get(subId));
1721 }
Jim Millerd72d5ac2015-09-29 18:55:32 -07001722 if (mFpm != null && mFpm.isHardwareDetected()) {
1723 final int userId = ActivityManager.getCurrentUser();
1724 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
1725 pw.println(" Fingerprint state (user=" + userId + ")");
1726 pw.println(" allowed=" + isUnlockingWithFingerprintAllowed());
1727 pw.println(" auth'd=" + mUserFingerprintAuthenticated.get(userId));
1728 pw.println(" authSinceBoot="
1729 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
1730 pw.println(" disabled(DPM)=" + isFingerprintDisabled(userId));
1731 pw.println(" possible=" + isUnlockWithFingerprintPossible(userId));
1732 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
1733 pw.println(" timedout=" + hasFingerprintUnlockTimedOut(userId));
1734 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
1735 }
Jason Monkab525272015-07-13 17:02:49 -04001736 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001737}