blob: 1e62646dc7ff8c2d7c5989634b3d10e0bebaa686 [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;
32
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080033import static android.os.BatteryManager.BATTERY_STATUS_FULL;
34import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
Jim Miller16464b82011-10-20 21:10:13 -070035import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
36import static android.os.BatteryManager.EXTRA_STATUS;
37import static android.os.BatteryManager.EXTRA_PLUGGED;
38import static android.os.BatteryManager.EXTRA_LEVEL;
39import static android.os.BatteryManager.EXTRA_HEALTH;
Adrian Roos7b043112015-07-10 13:00:33 -070040import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
Jim Miller06e34502014-07-17 14:46:05 -070041
Jim Miller47088bb2009-11-24 00:40:16 -080042import android.media.AudioManager;
Jim Miller79a444a2011-02-15 15:02:11 -080043import android.os.BatteryManager;
Jim Miller9f0753f2015-03-23 23:59:22 -070044import android.os.CancellationSignal;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080045import android.os.Handler;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070046import android.os.IRemoteCallback;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080047import android.os.Message;
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -070048import android.os.PowerManager;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070049import android.os.RemoteException;
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -070050import android.os.SystemClock;
Amith Yamasanie8e93a12013-05-09 18:12:30 -070051import android.os.UserHandle;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080052import android.provider.Settings;
Dianne Hackbornb7e787f2009-05-07 15:55:42 -070053
Wink Savillea639b312012-07-10 12:37:54 -070054import com.android.internal.telephony.IccCardConstants;
Jim Miller52a61332014-11-12 19:29:51 -080055import com.android.internal.telephony.IccCardConstants.State;
56import com.android.internal.telephony.PhoneConstants;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080057import com.android.internal.telephony.TelephonyIntents;
Jim Miller9f0753f2015-03-23 23:59:22 -070058
Jim Millerebbf2052015-03-31 17:24:34 -070059import android.hardware.fingerprint.FingerprintManager;
60import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
Jim Millerebbf2052015-03-31 17:24:34 -070061import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
Etan Cohen47051d82015-07-06 16:19:04 -070062import android.telephony.ServiceState;
Jim Miller52a61332014-11-12 19:29:51 -080063import android.telephony.SubscriptionInfo;
Jim Miller52a61332014-11-12 19:29:51 -080064import android.telephony.SubscriptionManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -080065import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Jim Millerc23024d2010-02-24 15:37:00 -080066import android.telephony.TelephonyManager;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -070067import android.util.ArraySet;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080068import android.util.Log;
Adrian Roos46842d92014-03-27 14:58:03 +010069import android.util.SparseBooleanArray;
Jorim Jaggi9f743032015-05-04 15:22:40 -070070import android.util.SparseIntArray;
Adrian Roos46842d92014-03-27 14:58:03 +010071
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080072import com.google.android.collect.Lists;
73
Jason Monkab525272015-07-13 17:02:49 -040074import java.io.FileDescriptor;
75import java.io.PrintWriter;
Jim Millerdcb3d842012-08-23 19:18:12 -070076import java.lang.ref.WeakReference;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080077import java.util.ArrayList;
Jim Miller52a61332014-11-12 19:29:51 -080078import java.util.HashMap;
79import java.util.List;
80import java.util.Map.Entry;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080081
82/**
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;
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -070097 private static final boolean DEBUG_FP_WAKELOCK = KeyguardConstants.DEBUG_FP_WAKELOCK;
Jim Millerbbf1a742012-07-17 18:30:30 -070098 private static final int LOW_BATTERY_THRESHOLD = 20;
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -070099 private static final long FINGERPRINT_WAKELOCK_TIMEOUT_MS = 15 * 1000;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800100
Jorim Jaggie7b12522014-08-06 16:41:21 +0200101 private static final String ACTION_FACE_UNLOCK_STARTED
102 = "com.android.facelock.FACE_UNLOCK_STARTED";
103 private static final String ACTION_FACE_UNLOCK_STOPPED
104 = "com.android.facelock.FACE_UNLOCK_STOPPED";
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700105 private static final String FINGERPRINT_WAKE_LOCK_NAME = "wake-and-unlock wakelock";
Jorim Jaggie7b12522014-08-06 16:41:21 +0200106
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700107 private static final String ACTION_STRONG_AUTH_TIMEOUT =
108 "com.android.systemui.ACTION_STRONG_AUTH_TIMEOUT";
109 private static final String USER_ID = "com.android.systemui.USER_ID";
110
111 private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
112
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700113 /**
114 * Mode in which we don't need to wake up the device when we get a fingerprint.
115 */
116 private static final int FP_WAKE_NONE = 0;
117
118 /**
119 * Mode in which we wake up the device, and directly dismiss Keyguard. Active when we acquire
120 * a fingerprint while the screen is off and the device was sleeping.
121 */
122 private static final int FP_WAKE_DIRECT_UNLOCK = 1;
123
124 /**
125 * Mode in which we wake up the device, but play the normal dismiss animation. Active when we
126 * acquire a fingerprint pulsing in doze mode.
127 * */
Jorim Jaggi959431b2015-07-28 13:19:38 -0700128 private static final int FP_WAKE_TO_BOUNCER = 2;
129
130 /**
131 * Mode in which we only wake up the device, and keyguard was not showing when we acquired a
132 * fingerprint.
133 * */
134 private static final int FP_ONLY_WAKE = 3;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700135
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700136 /**
137 * Milliseconds after unlocking with fingerprint times out, i.e. the user has to use a
138 * strong auth method like password, PIN or pattern.
139 */
140 private static final long FINGERPRINT_UNLOCK_TIMEOUT_MS = 72 * 60 * 60 * 1000;
141
Jim Millerbbf1a742012-07-17 18:30:30 -0700142 // Callback messages
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800143 private static final int MSG_TIME_UPDATE = 301;
144 private static final int MSG_BATTERY_UPDATE = 302;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800145 private static final int MSG_SIM_STATE_CHANGE = 304;
Jim Miller47088bb2009-11-24 00:40:16 -0800146 private static final int MSG_RINGER_MODE_CHANGED = 305;
Jim Millerc23024d2010-02-24 15:37:00 -0800147 private static final int MSG_PHONE_STATE_CHANGED = 306;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700148 private static final int MSG_DEVICE_PROVISIONED = 308;
Jim Miller57375342012-09-09 15:20:31 -0700149 private static final int MSG_DPM_STATE_CHANGED = 309;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500150 private static final int MSG_USER_SWITCHING = 310;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700151 private static final int MSG_KEYGUARD_VISIBILITY_CHANGED = 311;
152 private static final int MSG_KEYGUARD_RESET = 312;
Jim Millerf41fc962014-06-18 16:33:51 -0700153 private static final int MSG_BOOT_COMPLETED = 313;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500154 private static final int MSG_USER_SWITCH_COMPLETE = 314;
Jim Millerf41fc962014-06-18 16:33:51 -0700155 private static final int MSG_USER_INFO_CHANGED = 317;
156 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700157 private static final int MSG_STARTED_WAKING_UP = 319;
158 private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
Adrian Roosb6011622014-05-14 15:52:53 +0200159 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700160 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
161 private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
Jason Monk052082c2015-06-11 11:35:23 -0400162 private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
Etan Cohen47051d82015-07-06 16:19:04 -0700163 private static final int MSG_SERVICE_STATE_CHANGE = 330;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700164 private static final int MSG_SCREEN_TURNED_ON = 331;
165 private static final int MSG_SCREEN_TURNED_OFF = 332;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800166
Jim Millerdcb3d842012-08-23 19:18:12 -0700167 private static KeyguardUpdateMonitor sInstance;
168
Jim Millerbbf1a742012-07-17 18:30:30 -0700169 private final Context mContext;
Jim Miller52a61332014-11-12 19:29:51 -0800170 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
Etan Cohen47051d82015-07-06 16:19:04 -0700171 HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700172
Jim Millerbbf1a742012-07-17 18:30:30 -0700173 private int mRingMode;
174 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400175 private boolean mKeyguardIsVisible;
Adrian Roosb6011622014-05-14 15:52:53 +0200176 private boolean mBouncer;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800177 private boolean mBootCompleted;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700178 private boolean mUserHasAuthenticatedSinceBoot;
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. */
190 private ArraySet<Integer> mStrongAuthTimedOut = new ArraySet<>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700191
Jim Miller6212cc02012-09-05 17:35:31 -0700192 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700193 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800194 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700195
Brian Colonnaa5239892013-04-15 11:45:40 -0400196 private boolean mSwitchingUser;
197
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700198 private boolean mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -0700199 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800200 private SubscriptionManager mSubscriptionManager;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700201 private AlarmManager mAlarmManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800202 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700203 private boolean mFingerprintDetectionRunning;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700204 private TrustManager mTrustManager;
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700205 private PowerManager mPowerManager;
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;
Danielle Millettf6d0fc12012-10-23 16:16:52 -0400238 case MSG_KEYGUARD_VISIBILITY_CHANGED:
239 handleKeyguardVisibilityChanged(msg.arg1);
240 break;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700241 case MSG_KEYGUARD_RESET:
242 handleKeyguardReset();
243 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200244 case MSG_KEYGUARD_BOUNCER_CHANGED:
245 handleKeyguardBouncerChanged(msg.arg1);
246 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800247 case MSG_BOOT_COMPLETED:
248 handleBootCompleted();
249 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700250 case MSG_USER_INFO_CHANGED:
251 handleUserInfoChanged(msg.arg1);
252 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400253 case MSG_REPORT_EMERGENCY_CALL_ACTION:
254 handleReportEmergencyCallAction();
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
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700299 private int mFpWakeMode;
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700300
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700301 public synchronized static void setCurrentUser(int currentUser) {
302 sCurrentUser = currentUser;
303 }
304
305 public synchronized static int getCurrentUser() {
306 return sCurrentUser;
307 }
308
Adrian Roos46842d92014-03-27 14:58:03 +0100309 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700310 public void onTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos46842d92014-03-27 14:58:03 +0100311 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200312 for (int i = 0; i < mCallbacks.size(); i++) {
313 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
314 if (cb != null) {
315 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700316 if (enabled && flags != 0) {
317 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200318 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200319 }
320 }
Adrian Roos46842d92014-03-27 14:58:03 +0100321 }
322
Jim Miller52a61332014-11-12 19:29:51 -0800323 protected void handleSimSubscriptionInfoChanged() {
324 if (DEBUG_SIM_STATES) {
325 Log.v(TAG, "onSubscriptionInfoChanged()");
Wink Savilled09c4ca2014-11-22 10:08:16 -0800326 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
327 if (sil != null) {
328 for (SubscriptionInfo subInfo : sil) {
329 Log.v(TAG, "SubInfo:" + subInfo);
330 }
331 } else {
332 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800333 }
334 }
335 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
336
337 // Hack level over 9000: Because the subscription id is not yet valid when we see the
338 // first update in handleSimStateChange, we need to force refresh all all SIM states
339 // so the subscription id for them is consistent.
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100340 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
Jim Miller52a61332014-11-12 19:29:51 -0800341 for (int i = 0; i < subscriptionInfos.size(); i++) {
342 SubscriptionInfo info = subscriptionInfos.get(i);
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100343 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
344 if (changed) {
345 changedSubscriptions.add(info);
346 }
Jim Miller52a61332014-11-12 19:29:51 -0800347 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100348 for (int i = 0; i < changedSubscriptions.size(); i++) {
349 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800350 for (int j = 0; j < mCallbacks.size(); j++) {
351 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
352 if (cb != null) {
353 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
354 }
355 }
356 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500357 for (int j = 0; j < mCallbacks.size(); j++) {
358 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
359 if (cb != null) {
360 cb.onRefreshCarrierInfo();
361 }
362 }
Jim Miller52a61332014-11-12 19:29:51 -0800363 }
364
Jason Monk052082c2015-06-11 11:35:23 -0400365 private void handleAirplaneModeChanged() {
366 for (int j = 0; j < mCallbacks.size(); j++) {
367 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
368 if (cb != null) {
369 cb.onRefreshCarrierInfo();
370 }
371 }
372 }
373
Wink Savilled09c4ca2014-11-22 10:08:16 -0800374 /** @return List of SubscriptionInfo records, maybe empty but never null */
Jim Miller52a61332014-11-12 19:29:51 -0800375 List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800376 List<SubscriptionInfo> sil = mSubscriptionInfo;
377 if (sil == null || forceReload) {
378 sil = mSubscriptionManager.getActiveSubscriptionInfoList();
379 }
380 if (sil == null) {
381 // getActiveSubscriptionInfoList was null callers expect an empty list.
382 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
383 } else {
384 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800385 }
386 return mSubscriptionInfo;
387 }
388
Adrian Roos7861c662014-07-25 15:37:28 +0200389 @Override
390 public void onTrustManagedChanged(boolean managed, int userId) {
391 mUserTrustIsManaged.put(userId, managed);
392
393 for (int i = 0; i < mCallbacks.size(); i++) {
394 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
395 if (cb != null) {
396 cb.onTrustManagedChanged(userId);
397 }
398 }
399 }
400
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700401 private void onFingerprintAuthenticated(int userId, boolean wakeAndUnlocking) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700402 mUserFingerprintAuthenticated.put(userId, true);
Jim Millerf41fc962014-06-18 16:33:51 -0700403 for (int i = 0; i < mCallbacks.size(); i++) {
404 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
405 if (cb != null) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700406 cb.onFingerprintAuthenticated(userId, wakeAndUnlocking);
Jim Millerf41fc962014-06-18 16:33:51 -0700407 }
408 }
409 }
410
Jim Millerce7eb6d2015-04-03 19:29:13 -0700411 private void handleFingerprintAuthFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700412 releaseFingerprintWakeLock();
Jim Millerce7eb6d2015-04-03 19:29:13 -0700413 handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized));
414 }
Jim Millerf41fc962014-06-18 16:33:51 -0700415
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700416 private void handleFingerprintAcquired(int acquireInfo) {
417 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
418 return;
419 }
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700420 if (!mDeviceInteractive && !mScreenOn) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700421 releaseFingerprintWakeLock();
422 mWakeLock = mPowerManager.newWakeLock(
423 PowerManager.PARTIAL_WAKE_LOCK, FINGERPRINT_WAKE_LOCK_NAME);
424 mWakeLock.acquire();
Jorim Jaggi959431b2015-07-28 13:19:38 -0700425 mFpWakeMode = mKeyguardIsVisible ? FP_WAKE_DIRECT_UNLOCK : FP_ONLY_WAKE;
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700426 if (DEBUG_FP_WAKELOCK) {
427 Log.i(TAG, "fingerprint acquired, grabbing fp wakelock");
428 }
429 mHandler.postDelayed(mReleaseFingerprintWakeLockRunnable,
430 FINGERPRINT_WAKELOCK_TIMEOUT_MS);
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700431 } else if (!mDeviceInteractive) {
Jorim Jaggi959431b2015-07-28 13:19:38 -0700432 mFpWakeMode = FP_WAKE_TO_BOUNCER;
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700433 } else {
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700434 mFpWakeMode = FP_WAKE_NONE;
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700435 }
436 }
437
438 private final Runnable mReleaseFingerprintWakeLockRunnable = new Runnable() {
439 @Override
440 public void run() {
441 if (DEBUG_FP_WAKELOCK) {
442 Log.i(TAG, "fp wakelock: TIMEOUT!!");
443 }
444 releaseFingerprintWakeLock();
445 }
446 };
447
448 private void releaseFingerprintWakeLock() {
449 if (mWakeLock != null) {
450 mHandler.removeCallbacks(mReleaseFingerprintWakeLockRunnable);
451 if (DEBUG_FP_WAKELOCK) {
452 Log.i(TAG, "releasing fp wakelock");
453 }
454 mWakeLock.release();
455 mWakeLock = null;
456 }
457 }
458
Jim Miller4f364c92015-06-08 19:24:13 -0700459 private void handleFingerprintAuthenticated() {
Jorim Jaggi959431b2015-07-28 13:19:38 -0700460 if (mFpWakeMode == FP_WAKE_TO_BOUNCER || mFpWakeMode == FP_WAKE_DIRECT_UNLOCK
461 || mFpWakeMode == FP_ONLY_WAKE) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700462 if (DEBUG_FP_WAKELOCK) {
463 Log.i(TAG, "fp wakelock: Authenticated, waking up...");
464 }
465 mPowerManager.wakeUp(SystemClock.uptimeMillis());
466 }
467 releaseFingerprintWakeLock();
Jim Millerf41fc962014-06-18 16:33:51 -0700468 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700469 final int userId;
470 try {
471 userId = ActivityManagerNative.getDefault().getCurrentUser().id;
472 } catch (RemoteException e) {
473 Log.e(TAG, "Failed to get current user id: ", e);
474 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700475 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700476 if (isFingerprintDisabled(userId)) {
477 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
478 return;
479 }
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700480 onFingerprintAuthenticated(userId, mFpWakeMode == FP_WAKE_DIRECT_UNLOCK);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700481 } finally {
482 setFingerprintRunningDetectionRunning(false);
Jim Millerf41fc962014-06-18 16:33:51 -0700483 }
484 }
485
Jim Miller9f0753f2015-03-23 23:59:22 -0700486 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700487 for (int i = 0; i < mCallbacks.size(); i++) {
488 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
489 if (cb != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700490 cb.onFingerprintHelp(msgId, helpString);
491 }
492 }
493 }
494
495 private void handleFingerprintError(int msgId, String errString) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700496 setFingerprintRunningDetectionRunning(false);
Jim Miller9f0753f2015-03-23 23:59:22 -0700497 for (int i = 0; i < mCallbacks.size(); i++) {
498 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
499 if (cb != null) {
500 cb.onFingerprintError(msgId, errString);
Jim Millerf41fc962014-06-18 16:33:51 -0700501 }
502 }
503 }
504
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700505 private void setFingerprintRunningDetectionRunning(boolean running) {
506 if (running != mFingerprintDetectionRunning) {
507 mFingerprintDetectionRunning = running;
508 notifyFingerprintRunningStateChanged();
509 }
510 }
511
512 private void notifyFingerprintRunningStateChanged() {
513 for (int i = 0; i < mCallbacks.size(); i++) {
514 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
515 if (cb != null) {
516 cb.onFingerprintRunningStateChanged(mFingerprintDetectionRunning);
517 }
518 }
519 }
Adrian Roos4a410172014-08-20 17:41:44 +0200520 private void handleFaceUnlockStateChanged(boolean running, int userId) {
521 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200522 for (int i = 0; i < mCallbacks.size(); i++) {
523 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
524 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200525 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200526 }
527 }
528 }
529
Adrian Roos4a410172014-08-20 17:41:44 +0200530 public boolean isFaceUnlockRunning(int userId) {
531 return mUserFaceUnlockRunning.get(userId);
532 }
533
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700534 public boolean isFingerprintDetectionRunning() {
535 return mFingerprintDetectionRunning;
536 }
537
Jim Miller50e62182014-04-23 17:25:00 -0700538 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100539 // Don't allow trust agent if device is secured with a SIM PIN. This is here
540 // mainly because there's no other way to prompt the user to enter their SIM PIN
541 // once they get past the keyguard screen.
542 final boolean disabledBySimPin = isSimPinSecure();
543 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700544 }
545
Jim Miller06e34502014-07-17 14:46:05 -0700546 private boolean isFingerprintDisabled(int userId) {
547 final DevicePolicyManager dpm =
548 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
549 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
550 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0;
551 }
552
Selim Cineke8bae622015-07-15 13:24:06 -0700553 public boolean getUserCanSkipBouncer(int userId) {
Selim Cinek1fcafc42015-07-20 14:39:25 -0700554 return getUserHasTrust(userId) || (mUserFingerprintAuthenticated.get(userId)
555 && isUnlockingWithFingerprintAllowed());
Selim Cineke8bae622015-07-15 13:24:06 -0700556 }
557
Adrian Roos46842d92014-03-27 14:58:03 +0100558 public boolean getUserHasTrust(int userId) {
Selim Cineke8bae622015-07-15 13:24:06 -0700559 return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100560 }
561
Adrian Roos7861c662014-07-25 15:37:28 +0200562 public boolean getUserTrustIsManaged(int userId) {
563 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
564 }
565
Selim Cinek1fcafc42015-07-20 14:39:25 -0700566 public boolean isUnlockingWithFingerprintAllowed() {
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700567 return mUserHasAuthenticatedSinceBoot && !hasFingerprintUnlockTimedOut(sCurrentUser);
568 }
569
570 /**
571 * @return true if the user hasn't use strong authentication (pattern, PIN, password) since a
572 * while and thus can't unlock with fingerprint, false otherwise
573 */
574 public boolean hasFingerprintUnlockTimedOut(int userId) {
575 return mStrongAuthTimedOut.contains(userId);
576 }
577
578 public void reportSuccessfulStrongAuthUnlockAttempt() {
579 mStrongAuthTimedOut.remove(sCurrentUser);
580 scheduleStrongAuthTimeout();
Jim Millere0507bb2015-08-12 20:30:34 -0700581 if (mFpm != null) {
582 byte[] token = null; /* TODO: pass real auth token once fp HAL supports it */
583 mFpm.resetTimeout(token);
584 }
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700585 }
586
587 private void scheduleStrongAuthTimeout() {
588 long when = SystemClock.elapsedRealtime() + FINGERPRINT_UNLOCK_TIMEOUT_MS;
589 Intent intent = new Intent(ACTION_STRONG_AUTH_TIMEOUT);
590 intent.putExtra(USER_ID, sCurrentUser);
591 PendingIntent sender = PendingIntent.getBroadcast(mContext,
592 sCurrentUser, intent, PendingIntent.FLAG_CANCEL_CURRENT);
593 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, sender);
594 notifyStrongAuthTimedOutChanged(sCurrentUser);
595 }
596
597 private void notifyStrongAuthTimedOutChanged(int userId) {
598 for (int i = 0; i < mCallbacks.size(); i++) {
599 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
600 if (cb != null) {
601 cb.onStrongAuthTimeoutExpiredChanged(userId);
602 }
603 }
Selim Cinek1fcafc42015-07-20 14:39:25 -0700604 }
605
Jim Miller8f09fd22013-03-14 19:04:28 -0700606 static class DisplayClientState {
607 public int clientGeneration;
608 public boolean clearing;
609 public PendingIntent intent;
610 public int playbackState;
611 public long playbackEventTime;
612 }
613
614 private DisplayClientState mDisplayClientState = new DisplayClientState();
615
Jim Millerbbf1a742012-07-17 18:30:30 -0700616 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
617
Jim Miller8ae1be12015-08-05 13:03:21 -0700618 @Override
Jim Millerbbf1a742012-07-17 18:30:30 -0700619 public void onReceive(Context context, Intent intent) {
620 final String action = intent.getAction();
621 if (DEBUG) Log.d(TAG, "received broadcast " + action);
622
623 if (Intent.ACTION_TIME_TICK.equals(action)
624 || Intent.ACTION_TIME_CHANGED.equals(action)
Adrian Roos48c796c2014-09-01 14:59:23 +0200625 || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700626 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Jim Millerbbf1a742012-07-17 18:30:30 -0700627 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
628 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
629 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
630 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
631 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
Adrian Roos7b043112015-07-10 13:00:33 -0700632 final int maxChargingCurrent = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700633 final Message msg = mHandler.obtainMessage(
Adrian Roos7b043112015-07-10 13:00:33 -0700634 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
635 maxChargingCurrent));
Jim Millerbbf1a742012-07-17 18:30:30 -0700636 mHandler.sendMessage(msg);
637 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Jim Miller52a61332014-11-12 19:29:51 -0800638 SimData args = SimData.fromIntent(intent);
Jim Millerbbf1a742012-07-17 18:30:30 -0700639 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -0800640 Log.v(TAG, "action " + action
641 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
642 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -0700643 }
Jim Miller52a61332014-11-12 19:29:51 -0800644 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
645 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -0700646 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
647 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
648 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
649 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
650 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
651 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Jason Monk052082c2015-06-11 11:35:23 -0400652 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
653 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800654 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700655 dispatchBootCompleted();
Etan Cohen47051d82015-07-06 16:19:04 -0700656 } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
657 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
658 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
659 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
660 if (DEBUG) {
661 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
662 + subId);
663 }
664 mHandler.sendMessage(
665 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
Jim Millerbbf1a742012-07-17 18:30:30 -0700666 }
667 }
668 };
Jim Miller2de5ee82012-06-14 22:22:50 -0700669
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700670 private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
671
Jim Miller8ae1be12015-08-05 13:03:21 -0700672 @Override
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700673 public void onReceive(Context context, Intent intent) {
674 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +0200675 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
676 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
677 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700678 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
679 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +0200680 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
681 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
682 getSendingUserId()));
683 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
684 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
685 getSendingUserId()));
686 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
687 .equals(action)) {
688 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700689 }
690 }
691 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700692
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700693 private final BroadcastReceiver mStrongAuthTimeoutReceiver = new BroadcastReceiver() {
694 @Override
695 public void onReceive(Context context, Intent intent) {
696 if (ACTION_STRONG_AUTH_TIMEOUT.equals(intent.getAction())) {
697 int userId = intent.getIntExtra(USER_ID, -1);
698 mStrongAuthTimedOut.add(userId);
699 notifyStrongAuthTimedOutChanged(userId);
700 }
701 }
702 };
703
Jim Miller9f0753f2015-03-23 23:59:22 -0700704 private FingerprintManager.AuthenticationCallback mAuthenticationCallback
705 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -0700706
707 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -0700708 public void onAuthenticationFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700709 handleFingerprintAuthFailed();
Jim Millerce7eb6d2015-04-03 19:29:13 -0700710 };
711
712 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700713 public void onAuthenticationSucceeded(AuthenticationResult result) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700714 handleFingerprintAuthenticated();
Jim Millerf41fc962014-06-18 16:33:51 -0700715 }
716
717 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700718 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700719 handleFingerprintHelp(helpMsgId, helpString.toString());
Jim Miller9f0753f2015-03-23 23:59:22 -0700720 }
721
722 @Override
723 public void onAuthenticationError(int errMsgId, CharSequence errString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700724 handleFingerprintError(errMsgId, errString.toString());
725 }
726
727 @Override
728 public void onAuthenticationAcquired(int acquireInfo) {
729 handleFingerprintAcquired(acquireInfo);
Jim Millerf41fc962014-06-18 16:33:51 -0700730 }
731 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700732 private CancellationSignal mFingerprintCancelSignal;
733 private FingerprintManager mFpm;
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700734 private PowerManager.WakeLock mWakeLock;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700735
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800736 /**
Jim Miller47088bb2009-11-24 00:40:16 -0800737 * When we receive a
738 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -0700739 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800740 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -0800741 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800742 */
Jim Miller52a61332014-11-12 19:29:51 -0800743 private static class SimData {
744 public State simState;
745 public int slotId;
746 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800747
Jim Miller52a61332014-11-12 19:29:51 -0800748 SimData(State state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -0800749 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -0800750 slotId = slot;
751 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -0800752 }
753
Jim Miller52a61332014-11-12 19:29:51 -0800754 static SimData fromIntent(Intent intent) {
755 State state;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800756 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
757 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
758 }
Wink Savillea639b312012-07-10 12:37:54 -0700759 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
Jim Miller52a61332014-11-12 19:29:51 -0800760 int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0);
761 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
Wink Savilled09c4ca2014-11-22 10:08:16 -0800762 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea639b312012-07-10 12:37:54 -0700763 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -0700764 final String absentReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700765 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -0700766
Wink Savillea639b312012-07-10 12:37:54 -0700767 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -0700768 absentReason)) {
Wink Savillea639b312012-07-10 12:37:54 -0700769 state = IccCardConstants.State.PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -0700770 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700771 state = IccCardConstants.State.ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -0700772 }
Wink Savillea639b312012-07-10 12:37:54 -0700773 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
774 state = IccCardConstants.State.READY;
775 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800776 final String lockedReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700777 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
778 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
779 state = IccCardConstants.State.PIN_REQUIRED;
780 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
781 state = IccCardConstants.State.PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800782 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700783 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800784 }
Wink Savillea639b312012-07-10 12:37:54 -0700785 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
786 state = IccCardConstants.State.NETWORK_LOCKED;
Jim Miller109f1fd2012-09-19 20:44:16 -0700787 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
788 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
789 // This is required because telephony doesn't return to "READY" after
790 // these state transitions. See bug 7197471.
791 state = IccCardConstants.State.READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800792 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700793 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800794 }
Jim Miller52a61332014-11-12 19:29:51 -0800795 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800796 }
797
Jim Miller8ae1be12015-08-05 13:03:21 -0700798 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800799 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -0800800 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800801 }
802 }
803
Adrian Roos12c1ef52014-06-04 13:54:08 +0200804 public static class BatteryStatus {
Adrian Roos7b043112015-07-10 13:00:33 -0700805 public static final int CHARGING_UNKNOWN = -1;
806 public static final int CHARGING_SLOWLY = 0;
807 public static final int CHARGING_REGULAR = 1;
808 public static final int CHARGING_FAST = 2;
809
Jim Miller16464b82011-10-20 21:10:13 -0700810 public final int status;
811 public final int level;
812 public final int plugged;
813 public final int health;
Adrian Roos7b043112015-07-10 13:00:33 -0700814 public final int maxChargingCurrent;
815 public BatteryStatus(int status, int level, int plugged, int health, int maxChargingCurrent) {
Jim Miller16464b82011-10-20 21:10:13 -0700816 this.status = status;
817 this.level = level;
818 this.plugged = plugged;
819 this.health = health;
Adrian Roos7b043112015-07-10 13:00:33 -0700820 this.maxChargingCurrent = maxChargingCurrent;
Jim Miller16464b82011-10-20 21:10:13 -0700821 }
822
Jim Millerbbf1a742012-07-17 18:30:30 -0700823 /**
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700824 * Determine whether the device is plugged in (USB, power, or wireless).
Jim Millerbbf1a742012-07-17 18:30:30 -0700825 * @return true if the device is plugged in.
826 */
Adrian Roosad3bc7f2014-10-30 18:29:38 +0100827 public boolean isPluggedIn() {
Jim Millerbbf1a742012-07-17 18:30:30 -0700828 return plugged == BatteryManager.BATTERY_PLUGGED_AC
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700829 || plugged == BatteryManager.BATTERY_PLUGGED_USB
830 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Jim Millerbbf1a742012-07-17 18:30:30 -0700831 }
832
833 /**
834 * Whether or not the device is charged. Note that some devices never return 100% for
835 * battery level, so this allows either battery level or status to determine if the
836 * battery is charged.
837 * @return true if the device is charged
838 */
839 public boolean isCharged() {
840 return status == BATTERY_STATUS_FULL || level >= 100;
841 }
842
843 /**
844 * Whether battery is low and needs to be charged.
845 * @return true if battery is low
846 */
847 public boolean isBatteryLow() {
848 return level < LOW_BATTERY_THRESHOLD;
849 }
850
Adrian Roos7b043112015-07-10 13:00:33 -0700851 public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
852 return maxChargingCurrent <= 0 ? CHARGING_UNKNOWN :
853 maxChargingCurrent < slowThreshold ? CHARGING_SLOWLY :
854 maxChargingCurrent > fastThreshold ? CHARGING_FAST :
855 CHARGING_REGULAR;
856 }
Jim Miller16464b82011-10-20 21:10:13 -0700857 }
858
Jim Millerdcb3d842012-08-23 19:18:12 -0700859 public static KeyguardUpdateMonitor getInstance(Context context) {
860 if (sInstance == null) {
861 sInstance = new KeyguardUpdateMonitor(context);
862 }
863 return sInstance;
864 }
865
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700866 protected void handleStartedWakingUp() {
Jorim Jaggi864e64b2015-05-20 14:13:23 -0700867 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -0700868 final int count = mCallbacks.size();
869 for (int i = 0; i < count; i++) {
870 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
871 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700872 cb.onStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -0700873 }
874 }
875 }
876
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700877 protected void handleFinishedGoingToSleep(int arg1) {
Jim Millerf41fc962014-06-18 16:33:51 -0700878 clearFingerprintRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -0700879 final int count = mCallbacks.size();
880 for (int i = 0; i < count; i++) {
881 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
882 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700883 cb.onFinishedGoingToSleep(arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700884 }
885 }
Jorim Jaggiea657062015-04-28 13:45:11 -0700886 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -0700887 }
888
Jorim Jaggif1518da2015-07-30 11:56:36 -0700889 private void handleScreenTurnedOn() {
890 final int count = mCallbacks.size();
891 for (int i = 0; i < count; i++) {
892 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
893 if (cb != null) {
894 cb.onScreenTurnedOn();
895 }
896 }
897 }
898
899 private void handleScreenTurnedOff() {
900 final int count = mCallbacks.size();
901 for (int i = 0; i < count; i++) {
902 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
903 if (cb != null) {
904 cb.onScreenTurnedOff();
905 }
906 }
907 }
908
Adam Powell43a372f2013-09-27 17:43:53 -0700909 /**
910 * IMPORTANT: Must be called from UI thread.
911 */
912 public void dispatchSetBackground(Bitmap bmp) {
913 if (DEBUG) Log.d(TAG, "dispatchSetBackground");
914 final int count = mCallbacks.size();
915 for (int i = 0; i < count; i++) {
916 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
917 if (cb != null) {
918 cb.onSetBackground(bmp);
919 }
920 }
921 }
922
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700923 private void handleUserInfoChanged(int userId) {
924 for (int i = 0; i < mCallbacks.size(); i++) {
925 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
926 if (cb != null) {
927 cb.onUserInfoChanged(userId);
928 }
929 }
930 }
931
Jim Millerdcb3d842012-08-23 19:18:12 -0700932 private KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800933 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800934 mSubscriptionManager = SubscriptionManager.from(context);
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700935 mPowerManager = context.getSystemService(PowerManager.class);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700936 mAlarmManager = context.getSystemService(AlarmManager.class);
Michael Jurkafff56142012-11-28 16:51:00 -0800937 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700938
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800939 // Since device can't be un-provisioned, we only need to register a content observer
940 // to update mDeviceProvisioned when we are...
941 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700942 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800943 }
Jim Miller47088bb2009-11-24 00:40:16 -0800944
Jim Millerbbf1a742012-07-17 18:30:30 -0700945 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Adrian Roos7b043112015-07-10 13:00:33 -0700946 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800947
Jim Millerbbf1a742012-07-17 18:30:30 -0700948 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800949 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800950 filter.addAction(Intent.ACTION_TIME_TICK);
951 filter.addAction(Intent.ACTION_TIME_CHANGED);
952 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
953 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Jason Monk052082c2015-06-11 11:35:23 -0400954 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800955 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Etan Cohen47051d82015-07-06 16:19:04 -0700956 filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -0800957 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -0800958 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Jim Millerbbf1a742012-07-17 18:30:30 -0700959 context.registerReceiver(mBroadcastReceiver, filter);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700960
Adam Cohenc276e822012-11-08 13:01:08 -0800961 final IntentFilter bootCompleteFilter = new IntentFilter();
962 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
963 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
964 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter);
965
Adrian Roos48c796c2014-09-01 14:59:23 +0200966 final IntentFilter allUserFilter = new IntentFilter();
967 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
968 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
969 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
970 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
971 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
972 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700973 null, null);
974
Wink Saville071743f2015-01-12 17:11:04 -0800975 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700976 try {
977 ActivityManagerNative.getDefault().registerUserSwitchObserver(
978 new IUserSwitchObserver.Stub() {
979 @Override
980 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -0500981 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700982 newUserId, 0, reply));
983 }
984 @Override
985 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -0500986 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +0200987 newUserId, 0));
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700988 }
Kenny Guy42979622015-04-13 18:03:05 +0000989 @Override
990 public void onForegroundProfileSwitch(int newProfileId) {
991 // Ignore.
992 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700993 });
994 } catch (RemoteException e) {
995 // TODO Auto-generated catch block
996 e.printStackTrace();
997 }
Adrian Roos46842d92014-03-27 14:58:03 +0100998
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700999 IntentFilter strongAuthTimeoutFilter = new IntentFilter();
1000 strongAuthTimeoutFilter.addAction(ACTION_STRONG_AUTH_TIMEOUT);
1001 context.registerReceiver(mStrongAuthTimeoutReceiver, strongAuthTimeoutFilter,
1002 PERMISSION_SELF, null /* handler */);
Jorim Jaggi237b0612015-05-01 14:28:49 -07001003 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
1004 mTrustManager.registerTrustListener(this);
Jim Millerf41fc962014-06-18 16:33:51 -07001005
Jim Miller9f0753f2015-03-23 23:59:22 -07001006 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
Jorim Jaggiea657062015-04-28 13:45:11 -07001007 updateFingerprintListeningState();
1008 }
1009
1010 private void updateFingerprintListeningState() {
1011 boolean shouldListenForFingerprint = shouldListenForFingerprint();
1012 if (mFingerprintDetectionRunning && !shouldListenForFingerprint) {
1013 stopListeningForFingerprint();
1014 } else if (!mFingerprintDetectionRunning && shouldListenForFingerprint) {
1015 startListeningForFingerprint();
1016 }
1017 }
1018
1019 private boolean shouldListenForFingerprint() {
Jorim Jaggi959431b2015-07-28 13:19:38 -07001020 return (mKeyguardIsVisible || !mDeviceInteractive) && !mSwitchingUser;
Jim Miller9f0753f2015-03-23 23:59:22 -07001021 }
1022
Jim Millerce7eb6d2015-04-03 19:29:13 -07001023 private void startListeningForFingerprint() {
1024 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -07001025 int userId = ActivityManager.getCurrentUser();
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001026 if (isUnlockWithFingerprintPossible(userId)) {
Selim Cinek1fcafc42015-07-20 14:39:25 -07001027 mUserHasAuthenticatedSinceBoot = mTrustManager.hasUserAuthenticatedSinceBoot(
1028 ActivityManager.getCurrentUser());
Jim Millerce7eb6d2015-04-03 19:29:13 -07001029 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001030 mFingerprintCancelSignal.cancel();
1031 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001032 mFingerprintCancelSignal = new CancellationSignal();
Jim Millerf501b582015-06-03 16:36:31 -07001033 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null, userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -07001034 setFingerprintRunningDetectionRunning(true);
Jim Miller9f0753f2015-03-23 23:59:22 -07001035 }
1036 }
1037
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001038 public boolean isUnlockWithFingerprintPossible(int userId) {
Selim Cinek3122fa82015-06-18 01:38:59 -07001039 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
1040 && mFpm.getEnrolledFingerprints(userId).size() > 0;
1041 }
1042
Jorim Jaggiea657062015-04-28 13:45:11 -07001043 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001044 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
1045 if (isFingerprintDetectionRunning()) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001046 mFingerprintCancelSignal.cancel();
Jim Millerce7eb6d2015-04-03 19:29:13 -07001047 mFingerprintCancelSignal = null;
Jim Miller9f0753f2015-03-23 23:59:22 -07001048 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -07001049 setFingerprintRunningDetectionRunning(false);
Jim Millerbbf1a742012-07-17 18:30:30 -07001050 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001051
Michael Jurkafff56142012-11-28 16:51:00 -08001052 private boolean isDeviceProvisionedInSettingsDb() {
1053 return Settings.Global.getInt(mContext.getContentResolver(),
1054 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1055 }
1056
Jim Millerbbf1a742012-07-17 18:30:30 -07001057 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -08001058 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001059 @Override
1060 public void onChange(boolean selfChange) {
1061 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -08001062 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001063 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001064 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001065 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001066 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001067 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001068 };
1069
1070 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -07001071 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -08001072 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -07001073
1074 // prevent a race condition between where we check the flag and where we register the
1075 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -08001076 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001077 if (provisioned != mDeviceProvisioned) {
1078 mDeviceProvisioned = provisioned;
1079 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001080 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001081 }
1082 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001083 }
1084
Jim Millerbbf1a742012-07-17 18:30:30 -07001085 /**
1086 * Handle {@link #MSG_DPM_STATE_CHANGED}
1087 */
Jim Millerb0304762012-03-13 20:01:25 -07001088 protected void handleDevicePolicyManagerStateChanged() {
Jim Millerdcb3d842012-08-23 19:18:12 -07001089 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1090 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1091 if (cb != null) {
1092 cb.onDevicePolicyManagerStateChanged();
1093 }
Jim Millerb0304762012-03-13 20:01:25 -07001094 }
1095 }
1096
Jim Millerbbf1a742012-07-17 18:30:30 -07001097 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001098 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -07001099 */
Chris Wrenf41c61b2012-11-29 15:19:54 -05001100 protected void handleUserSwitching(int userId, IRemoteCallback reply) {
Jorim Jaggiaa4d32a2015-05-13 16:30:04 -07001101 mSwitchingUser = true;
1102 updateFingerprintListeningState();
1103
Jim Millerbbf1a742012-07-17 18:30:30 -07001104 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001105 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1106 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001107 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -07001108 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001109 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001110 try {
1111 reply.sendResult(null);
1112 } catch (RemoteException e) {
1113 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001114 }
1115
Jim Millerbbf1a742012-07-17 18:30:30 -07001116 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001117 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
1118 */
1119 protected void handleUserSwitchComplete(int userId) {
Jorim Jaggiaa4d32a2015-05-13 16:30:04 -07001120 mSwitchingUser = false;
1121 updateFingerprintListeningState();
1122
Chris Wrenf41c61b2012-11-29 15:19:54 -05001123 for (int i = 0; i < mCallbacks.size(); i++) {
1124 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1125 if (cb != null) {
1126 cb.onUserSwitchComplete(userId);
1127 }
1128 }
1129 }
1130
1131 /**
Jim Miller90873d52013-09-26 18:11:38 -07001132 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
1133 * keyguard crashes sometime after boot, then it will never receive this
1134 * broadcast and hence not handle the event. This method is ultimately called by
1135 * PhoneWindowManager in this case.
1136 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001137 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001138 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -07001139 }
1140
1141 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001142 * Handle {@link #MSG_BOOT_COMPLETED}
1143 */
1144 protected void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001145 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001146 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001147 for (int i = 0; i < mCallbacks.size(); i++) {
1148 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1149 if (cb != null) {
1150 cb.onBootCompleted();
1151 }
1152 }
1153 }
1154
1155 /**
Jim Miller5ecd8112013-01-09 18:50:26 -08001156 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001157 * destroyed.
1158 */
1159 public boolean hasBootCompleted() {
1160 return mBootCompleted;
1161 }
1162
1163 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001164 * Handle {@link #MSG_DEVICE_PROVISIONED}
1165 */
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001166 protected void handleDeviceProvisioned() {
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) {
1170 cb.onDeviceProvisioned();
1171 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001172 }
Michael Jurkafff56142012-11-28 16:51:00 -08001173 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001174 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -08001175 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
1176 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001177 }
1178 }
1179
Jim Millerbbf1a742012-07-17 18:30:30 -07001180 /**
1181 * Handle {@link #MSG_PHONE_STATE_CHANGED}
1182 */
Jim Millerc23024d2010-02-24 15:37:00 -08001183 protected void handlePhoneStateChanged(String newState) {
1184 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001185 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
1186 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
1187 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
1188 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
1189 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
1190 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
1191 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001192 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001193 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1194 if (cb != null) {
1195 cb.onPhoneStateChanged(mPhoneState);
1196 }
Jim Millerc23024d2010-02-24 15:37:00 -08001197 }
1198 }
1199
Jim Millerbbf1a742012-07-17 18:30:30 -07001200 /**
1201 * Handle {@link #MSG_RINGER_MODE_CHANGED}
1202 */
Jim Miller47088bb2009-11-24 00:40:16 -08001203 protected void handleRingerModeChange(int mode) {
1204 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001205 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -07001206 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001207 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1208 if (cb != null) {
1209 cb.onRingerModeChanged(mode);
1210 }
Jim Miller47088bb2009-11-24 00:40:16 -08001211 }
1212 }
1213
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001214 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001215 * Handle {@link #MSG_TIME_UPDATE}
1216 */
1217 private void handleTimeUpdate() {
1218 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001219 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001220 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1221 if (cb != null) {
1222 cb.onTimeChanged();
1223 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001224 }
1225 }
1226
1227 /**
1228 * Handle {@link #MSG_BATTERY_UPDATE}
1229 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001230 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001231 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001232 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
1233 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07001234 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001235 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001236 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1237 if (cb != null) {
1238 cb.onRefreshBatteryInfo(status);
1239 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001240 }
1241 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001242 }
1243
1244 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001245 * Handle {@link #MSG_SIM_STATE_CHANGE}
1246 */
Jim Miller52a61332014-11-12 19:29:51 -08001247 private void handleSimStateChange(int subId, int slotId, State state) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001248
Jim Miller52a61332014-11-12 19:29:51 -08001249 if (DEBUG_SIM_STATES) {
1250 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
1251 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001252 }
1253
Wink Savillea54bf652014-12-11 13:37:50 -08001254 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08001255 Log.w(TAG, "invalid subId in handleSimStateChange()");
1256 return;
1257 }
1258
1259 SimData data = mSimDatas.get(subId);
1260 final boolean changed;
1261 if (data == null) {
1262 data = new SimData(state, slotId, subId);
1263 mSimDatas.put(subId, data);
1264 changed = true; // no data yet; force update
1265 } else {
1266 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
1267 data.simState = state;
1268 data.subId = subId;
1269 data.slotId = slotId;
1270 }
1271 if (changed && state != State.UNKNOWN) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001272 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001273 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1274 if (cb != null) {
Jim Miller52a61332014-11-12 19:29:51 -08001275 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07001276 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001277 }
1278 }
1279 }
1280
Jim Millerbbf1a742012-07-17 18:30:30 -07001281 /**
Etan Cohen47051d82015-07-06 16:19:04 -07001282 * Handle {@link #MSG_SERVICE_STATE_CHANGE}
1283 */
1284 private void handleServiceStateChange(int subId, ServiceState serviceState) {
1285 if (DEBUG) {
1286 Log.d(TAG,
1287 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
1288 }
1289
1290 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1291 Log.w(TAG, "invalid subId in handleServiceStateChange()");
1292 return;
1293 }
1294
1295 mServiceStates.put(subId, serviceState);
1296
1297 for (int j = 0; j < mCallbacks.size(); j++) {
1298 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
1299 if (cb != null) {
1300 cb.onRefreshCarrierInfo();
1301 }
1302 }
1303 }
1304
1305 /**
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001306 * Handle {@link #MSG_KEYGUARD_VISIBILITY_CHANGED}
1307 */
1308 private void handleKeyguardVisibilityChanged(int showing) {
1309 if (DEBUG) Log.d(TAG, "handleKeyguardVisibilityChanged(" + showing + ")");
Danielle Millett5d2404d2012-11-01 00:05:27 -04001310 boolean isShowing = (showing == 1);
1311 mKeyguardIsVisible = isShowing;
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001312 for (int i = 0; i < mCallbacks.size(); i++) {
1313 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1314 if (cb != null) {
John Spurlock385a63d2013-10-30 19:40:48 -04001315 cb.onKeyguardVisibilityChangedRaw(isShowing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001316 }
1317 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001318 updateFingerprintListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001319 }
1320
Brian Colonna7fce3802013-09-17 15:51:32 -04001321 /**
Selim Cinek1fcafc42015-07-20 14:39:25 -07001322 * Handle {@link #MSG_KEYGUARD_RESET}
1323 */
1324 private void handleKeyguardReset() {
1325 if (DEBUG) Log.d(TAG, "handleKeyguardReset");
1326 if (!isUnlockingWithFingerprintAllowed()) {
1327 updateFingerprintListeningState();
1328 }
1329 }
1330
1331 /**
Adrian Roosb6011622014-05-14 15:52:53 +02001332 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
1333 * @see #sendKeyguardBouncerChanged(boolean)
1334 */
1335 private void handleKeyguardBouncerChanged(int bouncer) {
1336 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
1337 boolean isBouncer = (bouncer == 1);
1338 mBouncer = isBouncer;
1339 for (int i = 0; i < mCallbacks.size(); i++) {
1340 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1341 if (cb != null) {
1342 cb.onKeyguardBouncerChanged(isBouncer);
1343 }
1344 }
1345 }
1346
1347 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04001348 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
1349 */
1350 private void handleReportEmergencyCallAction() {
1351 for (int i = 0; i < mCallbacks.size(); i++) {
1352 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1353 if (cb != null) {
1354 cb.onEmergencyCallAction();
1355 }
1356 }
1357 }
1358
Jim Miller16464b82011-10-20 21:10:13 -07001359 private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001360 final boolean nowPluggedIn = current.isPluggedIn();
1361 final boolean wasPluggedIn = old.isPluggedIn();
Jim Miller79a444a2011-02-15 15:02:11 -08001362 final boolean stateChangedWhilePluggedIn =
Jim Miller16464b82011-10-20 21:10:13 -07001363 wasPluggedIn == true && nowPluggedIn == true
1364 && (old.status != current.status);
1365
1366 // change in plug state is always interesting
1367 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001368 return true;
1369 }
1370
1371 // change in battery level while plugged in
Jim Miller16464b82011-10-20 21:10:13 -07001372 if (nowPluggedIn && old.level != current.level) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001373 return true;
1374 }
1375
Jim Miller16464b82011-10-20 21:10:13 -07001376 // change where battery needs charging
Jim Millerbbf1a742012-07-17 18:30:30 -07001377 if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
Jim Miller16464b82011-10-20 21:10:13 -07001378 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001379 }
Adrian Roos76dc5a52015-07-21 16:20:36 -07001380
1381 // change in charging current while plugged in
1382 if (nowPluggedIn && current.maxChargingCurrent != old.maxChargingCurrent) {
1383 return true;
1384 }
1385
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001386 return false;
1387 }
1388
1389 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001390 * Remove the given observer's callback.
1391 *
Jim Miller6212cc02012-09-05 17:35:31 -07001392 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001393 */
Jim Miller6212cc02012-09-05 17:35:31 -07001394 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
1395 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
1396 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1397 if (mCallbacks.get(i).get() == callback) {
1398 mCallbacks.remove(i);
1399 }
1400 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001401 }
1402
1403 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001404 * Register to receive notifications about general keyguard information
1405 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07001406 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001407 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001408 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Jim Miller6212cc02012-09-05 17:35:31 -07001409 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
1410 // Prevent adding duplicate callbacks
1411 for (int i = 0; i < mCallbacks.size(); i++) {
1412 if (mCallbacks.get(i).get() == callback) {
1413 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
1414 new Exception("Called by"));
1415 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07001416 }
1417 }
Jim Miller6212cc02012-09-05 17:35:31 -07001418 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
1419 removeCallback(null); // remove unused references
1420 sendUpdates(callback);
1421 }
1422
1423 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
1424 // Notify listener of the current state
1425 callback.onRefreshBatteryInfo(mBatteryStatus);
1426 callback.onTimeChanged();
1427 callback.onRingerModeChanged(mRingMode);
1428 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05001429 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07001430 callback.onClockVisibilityChanged();
Jim Miller52a61332014-11-12 19:29:51 -08001431 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
1432 final SimData state = data.getValue();
1433 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
1434 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001435 }
1436
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001437 public void sendKeyguardVisibilityChanged(boolean showing) {
1438 if (DEBUG) Log.d(TAG, "sendKeyguardVisibilityChanged(" + showing + ")");
1439 Message message = mHandler.obtainMessage(MSG_KEYGUARD_VISIBILITY_CHANGED);
1440 message.arg1 = showing ? 1 : 0;
1441 message.sendToTarget();
1442 }
1443
Selim Cinek1fcafc42015-07-20 14:39:25 -07001444 public void sendKeyguardReset() {
1445 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
1446 }
1447
Adrian Roosb6011622014-05-14 15:52:53 +02001448 /**
1449 * @see #handleKeyguardBouncerChanged(int)
1450 */
1451 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
1452 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
1453 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
1454 message.arg1 = showingBouncer ? 1 : 0;
1455 message.sendToTarget();
1456 }
1457
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001458 /**
Jim Miller90d5d462011-11-17 16:57:01 -08001459 * 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 -08001460 * have the information earlier than waiting for the intent
1461 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08001462 *
1463 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
1464 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001465 */
Jim Miller52a61332014-11-12 19:29:51 -08001466 public void reportSimUnlocked(int subId) {
1467 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
1468 int slotId = SubscriptionManager.getSlotId(subId);
1469 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001470 }
1471
Brian Colonna7fce3802013-09-17 15:51:32 -04001472 /**
1473 * Report that the emergency call button has been pressed and the emergency dialer is
1474 * about to be displayed.
1475 *
1476 * @param bypassHandler runs immediately.
1477 *
1478 * NOTE: Must be called from UI thread if bypassHandler == true.
1479 */
1480 public void reportEmergencyCallAction(boolean bypassHandler) {
1481 if (!bypassHandler) {
1482 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
1483 } else {
1484 handleReportEmergencyCallAction();
1485 }
1486 }
1487
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001488 /**
1489 * @return Whether the device is provisioned (whether they have gone through
1490 * the setup wizard)
1491 */
1492 public boolean isDeviceProvisioned() {
1493 return mDeviceProvisioned;
1494 }
1495
Jorim Jaggi9f743032015-05-04 15:22:40 -07001496 public void clearFailedUnlockAttempts() {
1497 mFailedAttempts.delete(sCurrentUser);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001498 }
1499
Jorim Jaggi9f743032015-05-04 15:22:40 -07001500 public int getFailedUnlockAttempts() {
1501 return mFailedAttempts.get(sCurrentUser, 0);
1502 }
1503
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001504 public void reportFailedStrongAuthUnlockAttempt() {
Jorim Jaggi9f743032015-05-04 15:22:40 -07001505 mFailedAttempts.put(sCurrentUser, getFailedUnlockAttempts() + 1);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001506 }
1507
Jim Millerf41fc962014-06-18 16:33:51 -07001508 public void clearFingerprintRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07001509 mUserFingerprintAuthenticated.clear();
Jim Millerf41fc962014-06-18 16:33:51 -07001510 }
1511
Jim Miller52a61332014-11-12 19:29:51 -08001512 public boolean isSimPinVoiceSecure() {
1513 // TODO: only count SIMs that handle voice
1514 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07001515 }
1516
1517 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08001518 // True if any SIM is pin secure
1519 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
1520 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
1521 }
1522 return false;
1523 }
1524
Jason Monk9ff69bd2014-12-02 16:43:17 -05001525 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08001526 if (mSimDatas.containsKey(subId)) {
1527 return mSimDatas.get(subId).simState;
1528 } else {
1529 return State.UNKNOWN;
1530 }
1531 }
1532
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001533 /**
1534 * @return true if and only if the state has changed for the specified {@code slotId}
1535 */
1536 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08001537
1538 // This is awful. It exists because there are two APIs for getting the SIM status
1539 // that don't return the complete set of values and have different types. In Keyguard we
1540 // need IccCardConstants, but TelephonyManager would only give us
1541 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08001542 final TelephonyManager tele = TelephonyManager.from(mContext);
1543 int simState = tele.getSimState(slotId);
Jim Miller52a61332014-11-12 19:29:51 -08001544 State state;
1545 try {
xinhe18b9c3c2014-12-02 15:03:20 -08001546 state = State.intToState(simState);
Jim Miller52a61332014-11-12 19:29:51 -08001547 } catch(IllegalArgumentException ex) {
xinhe18b9c3c2014-12-02 15:03:20 -08001548 Log.w(TAG, "Unknown sim state: " + simState);
Jim Miller52a61332014-11-12 19:29:51 -08001549 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05001550 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001551 SimData data = mSimDatas.get(subId);
1552 final boolean changed;
1553 if (data == null) {
1554 data = new SimData(state, slotId, subId);
1555 mSimDatas.put(subId, data);
1556 changed = true; // no data yet; force update
1557 } else {
1558 changed = data.simState != state;
1559 data.simState = state;
1560 }
1561 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07001562 }
1563
1564 public static boolean isSimPinSecure(IccCardConstants.State state) {
1565 final IccCardConstants.State simState = state;
1566 return (simState == IccCardConstants.State.PIN_REQUIRED
1567 || simState == IccCardConstants.State.PUK_REQUIRED
1568 || simState == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07001569 }
Jim Miller8f09fd22013-03-14 19:04:28 -07001570
1571 public DisplayClientState getCachedDisplayClientState() {
1572 return mDisplayClientState;
1573 }
Jim Miller20daffd2013-10-07 14:59:53 -07001574
1575 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
1576 // (KeyguardViewMediator, KeyguardHostView)
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001577 public void dispatchStartedWakingUp() {
1578 synchronized (this) {
1579 mDeviceInteractive = true;
1580 }
1581 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
1582 }
1583
1584 public void dispatchFinishedGoingToSleep(int why) {
1585 synchronized(this) {
1586 mDeviceInteractive = false;
1587 }
1588 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
1589 }
1590
Jim Miller20daffd2013-10-07 14:59:53 -07001591 public void dispatchScreenTurnedOn() {
1592 synchronized (this) {
1593 mScreenOn = true;
1594 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001595 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
Jim Miller20daffd2013-10-07 14:59:53 -07001596 }
1597
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001598 public void dispatchScreenTurnedOff() {
Jim Miller20daffd2013-10-07 14:59:53 -07001599 synchronized(this) {
1600 mScreenOn = false;
1601 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001602 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
Jim Miller20daffd2013-10-07 14:59:53 -07001603 }
1604
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001605 public boolean isDeviceInteractive() {
1606 return mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -07001607 }
Jim Miller52a61332014-11-12 19:29:51 -08001608
1609 /**
1610 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
1611 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08001612 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08001613 */
1614 public int getNextSubIdForState(State state) {
1615 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08001616 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08001617 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
1618 for (int i = 0; i < list.size(); i++) {
1619 final SubscriptionInfo info = list.get(i);
1620 final int id = info.getSubscriptionId();
1621 int slotId = SubscriptionManager.getSlotId(id);
1622 if (state == getSimState(id) && bestSlotId > slotId ) {
1623 resultId = id;
1624 bestSlotId = slotId;
1625 }
1626 }
1627 return resultId;
1628 }
1629
1630 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
1631 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
1632 for (int i = 0; i < list.size(); i++) {
1633 SubscriptionInfo info = list.get(i);
1634 if (subId == info.getSubscriptionId()) return info;
1635 }
1636 return null; // not found
1637 }
Jason Monkab525272015-07-13 17:02:49 -04001638
1639 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1640 pw.println("KeyguardUpdateMonitor state:");
1641 pw.println(" SIM States:");
1642 for (SimData data : mSimDatas.values()) {
1643 pw.println(" " + data.toString());
1644 }
1645 pw.println(" Subs:");
1646 if (mSubscriptionInfo != null) {
1647 for (int i = 0; i < mSubscriptionInfo.size(); i++) {
1648 pw.println(" " + mSubscriptionInfo.get(i));
1649 }
1650 }
1651 pw.println(" Service states:");
1652 for (int subId : mServiceStates.keySet()) {
1653 pw.println(" " + subId + "=" + mServiceStates.get(subId));
1654 }
1655 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001656}