blob: 40dcd0d86dc1ca5bb428b3900da3e1a6c9572e35 [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;
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_VISIBILITY_CHANGED = 311;
126 private static final int MSG_KEYGUARD_RESET = 312;
Jim Millerf41fc962014-06-18 16:33:51 -0700127 private static final int MSG_BOOT_COMPLETED = 313;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500128 private static final int MSG_USER_SWITCH_COMPLETE = 314;
Jim Millerf41fc962014-06-18 16:33:51 -0700129 private static final int MSG_USER_INFO_CHANGED = 317;
130 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700131 private static final int MSG_STARTED_WAKING_UP = 319;
132 private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
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
Jim Millerdcb3d842012-08-23 19:18:12 -0700141 private static KeyguardUpdateMonitor sInstance;
142
Jim Millerbbf1a742012-07-17 18:30:30 -0700143 private final Context mContext;
Jim Miller52a61332014-11-12 19:29:51 -0800144 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
Etan Cohen47051d82015-07-06 16:19:04 -0700145 HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700146
Jim Millerbbf1a742012-07-17 18:30:30 -0700147 private int mRingMode;
148 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400149 private boolean mKeyguardIsVisible;
Jorim Jaggi71448a72015-08-18 19:49:04 -0700150
151 /**
152 * If true, fingerprint was already authenticated and we don't need to start listening again
153 * until the Keyguard has been dismissed.
154 */
155 private boolean mFingerprintAlreadyAuthenticated;
Adrian Roosb6011622014-05-14 15:52:53 +0200156 private boolean mBouncer;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800157 private boolean mBootCompleted;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700158 private boolean mUserHasAuthenticatedSinceBoot;
Jim Millerbbf1a742012-07-17 18:30:30 -0700159
Jim Millerdcb3d842012-08-23 19:18:12 -0700160 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700161 private boolean mDeviceProvisioned;
162
Jim Millerdcb3d842012-08-23 19:18:12 -0700163 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700164 private BatteryStatus mBatteryStatus;
165
Jim Millerdcb3d842012-08-23 19:18:12 -0700166 // Password attempts
Jorim Jaggi9f743032015-05-04 15:22:40 -0700167 private SparseIntArray mFailedAttempts = new SparseIntArray();
Brian Colonnacc4104f2012-10-09 17:50:46 -0400168
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700169 /** Tracks whether strong authentication hasn't been used since quite some time per user. */
170 private ArraySet<Integer> mStrongAuthTimedOut = new ArraySet<>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700171
Jim Miller6212cc02012-09-05 17:35:31 -0700172 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700173 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800174 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700175
Brian Colonnaa5239892013-04-15 11:45:40 -0400176 private boolean mSwitchingUser;
177
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700178 private boolean mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -0700179 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800180 private SubscriptionManager mSubscriptionManager;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700181 private AlarmManager mAlarmManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800182 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700183 private boolean mFingerprintDetectionRunning;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700184 private TrustManager mTrustManager;
Jim Miller20daffd2013-10-07 14:59:53 -0700185
Jim Millerbbf1a742012-07-17 18:30:30 -0700186 private final Handler mHandler = new Handler() {
187 @Override
188 public void handleMessage(Message msg) {
189 switch (msg.what) {
190 case MSG_TIME_UPDATE:
191 handleTimeUpdate();
192 break;
193 case MSG_BATTERY_UPDATE:
194 handleBatteryUpdate((BatteryStatus) msg.obj);
195 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700196 case MSG_SIM_STATE_CHANGE:
Jim Miller52a61332014-11-12 19:29:51 -0800197 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700198 break;
199 case MSG_RINGER_MODE_CHANGED:
200 handleRingerModeChange(msg.arg1);
201 break;
202 case MSG_PHONE_STATE_CHANGED:
Adrian Roosb6011622014-05-14 15:52:53 +0200203 handlePhoneStateChanged((String) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700204 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700205 case MSG_DEVICE_PROVISIONED:
206 handleDeviceProvisioned();
207 break;
208 case MSG_DPM_STATE_CHANGED:
209 handleDevicePolicyManagerStateChanged();
210 break;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500211 case MSG_USER_SWITCHING:
Adrian Roosb6011622014-05-14 15:52:53 +0200212 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
Chris Wrenf41c61b2012-11-29 15:19:54 -0500213 break;
214 case MSG_USER_SWITCH_COMPLETE:
215 handleUserSwitchComplete(msg.arg1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700216 break;
Danielle Millettf6d0fc12012-10-23 16:16:52 -0400217 case MSG_KEYGUARD_VISIBILITY_CHANGED:
218 handleKeyguardVisibilityChanged(msg.arg1);
219 break;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700220 case MSG_KEYGUARD_RESET:
221 handleKeyguardReset();
222 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200223 case MSG_KEYGUARD_BOUNCER_CHANGED:
224 handleKeyguardBouncerChanged(msg.arg1);
225 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800226 case MSG_BOOT_COMPLETED:
227 handleBootCompleted();
228 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700229 case MSG_USER_INFO_CHANGED:
230 handleUserInfoChanged(msg.arg1);
231 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400232 case MSG_REPORT_EMERGENCY_CALL_ACTION:
233 handleReportEmergencyCallAction();
234 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700235 case MSG_FINISHED_GOING_TO_SLEEP:
236 handleFinishedGoingToSleep(msg.arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700237 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700238 case MSG_STARTED_WAKING_UP:
239 handleStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -0700240 break;
Jorim Jaggie7b12522014-08-06 16:41:21 +0200241 case MSG_FACE_UNLOCK_STATE_CHANGED:
Adrian Roos4a410172014-08-20 17:41:44 +0200242 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200243 break;
Jim Miller52a61332014-11-12 19:29:51 -0800244 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
245 handleSimSubscriptionInfoChanged();
246 break;
Jason Monk052082c2015-06-11 11:35:23 -0400247 case MSG_AIRPLANE_MODE_CHANGED:
248 handleAirplaneModeChanged();
249 break;
Etan Cohen47051d82015-07-06 16:19:04 -0700250 case MSG_SERVICE_STATE_CHANGE:
251 handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
252 break;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700253 case MSG_SCREEN_TURNED_ON:
254 handleScreenTurnedOn();
255 break;
256 case MSG_SCREEN_TURNED_OFF:
257 handleScreenTurnedOff();
258 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700259 }
260 }
261 };
262
Wink Savilled09c4ca2014-11-22 10:08:16 -0800263 private OnSubscriptionsChangedListener mSubscriptionListener =
264 new OnSubscriptionsChangedListener() {
Jim Miller52a61332014-11-12 19:29:51 -0800265 @Override
Wink Savilled09c4ca2014-11-22 10:08:16 -0800266 public void onSubscriptionsChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800267 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
268 }
269 };
270
Adrian Roos46842d92014-03-27 14:58:03 +0100271 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200272 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Jim Miller9f0753f2015-03-23 23:59:22 -0700273 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200274 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100275
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700276 private static int sCurrentUser;
277
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700278 private int mFpWakeMode;
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700279
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700280 public synchronized static void setCurrentUser(int currentUser) {
281 sCurrentUser = currentUser;
282 }
283
284 public synchronized static int getCurrentUser() {
285 return sCurrentUser;
286 }
287
Adrian Roos46842d92014-03-27 14:58:03 +0100288 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700289 public void onTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos46842d92014-03-27 14:58:03 +0100290 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200291 for (int i = 0; i < mCallbacks.size(); i++) {
292 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
293 if (cb != null) {
294 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700295 if (enabled && flags != 0) {
296 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200297 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200298 }
299 }
Adrian Roos46842d92014-03-27 14:58:03 +0100300 }
301
Jim Miller52a61332014-11-12 19:29:51 -0800302 protected void handleSimSubscriptionInfoChanged() {
303 if (DEBUG_SIM_STATES) {
304 Log.v(TAG, "onSubscriptionInfoChanged()");
Wink Savilled09c4ca2014-11-22 10:08:16 -0800305 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
306 if (sil != null) {
307 for (SubscriptionInfo subInfo : sil) {
308 Log.v(TAG, "SubInfo:" + subInfo);
309 }
310 } else {
311 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800312 }
313 }
314 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
315
316 // Hack level over 9000: Because the subscription id is not yet valid when we see the
317 // first update in handleSimStateChange, we need to force refresh all all SIM states
318 // so the subscription id for them is consistent.
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100319 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
Jim Miller52a61332014-11-12 19:29:51 -0800320 for (int i = 0; i < subscriptionInfos.size(); i++) {
321 SubscriptionInfo info = subscriptionInfos.get(i);
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100322 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
323 if (changed) {
324 changedSubscriptions.add(info);
325 }
Jim Miller52a61332014-11-12 19:29:51 -0800326 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100327 for (int i = 0; i < changedSubscriptions.size(); i++) {
328 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800329 for (int j = 0; j < mCallbacks.size(); j++) {
330 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
331 if (cb != null) {
332 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
333 }
334 }
335 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500336 for (int j = 0; j < mCallbacks.size(); j++) {
337 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
338 if (cb != null) {
339 cb.onRefreshCarrierInfo();
340 }
341 }
Jim Miller52a61332014-11-12 19:29:51 -0800342 }
343
Jason Monk052082c2015-06-11 11:35:23 -0400344 private void handleAirplaneModeChanged() {
345 for (int j = 0; j < mCallbacks.size(); j++) {
346 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
347 if (cb != null) {
348 cb.onRefreshCarrierInfo();
349 }
350 }
351 }
352
Wink Savilled09c4ca2014-11-22 10:08:16 -0800353 /** @return List of SubscriptionInfo records, maybe empty but never null */
Jim Miller52a61332014-11-12 19:29:51 -0800354 List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800355 List<SubscriptionInfo> sil = mSubscriptionInfo;
356 if (sil == null || forceReload) {
357 sil = mSubscriptionManager.getActiveSubscriptionInfoList();
358 }
359 if (sil == null) {
360 // getActiveSubscriptionInfoList was null callers expect an empty list.
361 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
362 } else {
363 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800364 }
365 return mSubscriptionInfo;
366 }
367
Adrian Roos7861c662014-07-25 15:37:28 +0200368 @Override
369 public void onTrustManagedChanged(boolean managed, int userId) {
370 mUserTrustIsManaged.put(userId, managed);
371
372 for (int i = 0; i < mCallbacks.size(); i++) {
373 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
374 if (cb != null) {
375 cb.onTrustManagedChanged(userId);
376 }
377 }
378 }
379
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700380 private void onFingerprintAuthenticated(int userId) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700381 mUserFingerprintAuthenticated.put(userId, true);
Jorim Jaggi71448a72015-08-18 19:49:04 -0700382
383 // If fingerprint unlocking is allowed, this event will lead to a Keyguard dismiss or to a
384 // wake-up (if Keyguard is not showing), so we don't need to listen until Keyguard is
385 // fully gone.
386 mFingerprintAlreadyAuthenticated = isUnlockingWithFingerprintAllowed();
Jim Millerf41fc962014-06-18 16:33:51 -0700387 for (int i = 0; i < mCallbacks.size(); i++) {
388 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
389 if (cb != null) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700390 cb.onFingerprintAuthenticated(userId);
Jim Millerf41fc962014-06-18 16:33:51 -0700391 }
392 }
393 }
394
Jim Millerce7eb6d2015-04-03 19:29:13 -0700395 private void handleFingerprintAuthFailed() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700396 for (int i = 0; i < mCallbacks.size(); i++) {
397 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
398 if (cb != null) {
399 cb.onFingerprintAuthFailed();
400 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700401 }
Jim Millerce7eb6d2015-04-03 19:29:13 -0700402 handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized));
403 }
Jim Millerf41fc962014-06-18 16:33:51 -0700404
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700405 private void handleFingerprintAcquired(int acquireInfo) {
406 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
407 return;
408 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700409 for (int i = 0; i < mCallbacks.size(); i++) {
410 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
411 if (cb != null) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700412 cb.onFingerprintAcquired();
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700413 }
414 }
415 }
416
Jim Miller4f364c92015-06-08 19:24:13 -0700417 private void handleFingerprintAuthenticated() {
Jim Millerf41fc962014-06-18 16:33:51 -0700418 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700419 final int userId;
420 try {
421 userId = ActivityManagerNative.getDefault().getCurrentUser().id;
422 } catch (RemoteException e) {
423 Log.e(TAG, "Failed to get current user id: ", e);
424 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700425 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700426 if (isFingerprintDisabled(userId)) {
427 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
428 return;
429 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700430 onFingerprintAuthenticated(userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700431 } finally {
432 setFingerprintRunningDetectionRunning(false);
Jim Millerf41fc962014-06-18 16:33:51 -0700433 }
434 }
435
Jim Miller9f0753f2015-03-23 23:59:22 -0700436 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700437 for (int i = 0; i < mCallbacks.size(); i++) {
438 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
439 if (cb != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700440 cb.onFingerprintHelp(msgId, helpString);
441 }
442 }
443 }
444
445 private void handleFingerprintError(int msgId, String errString) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700446 setFingerprintRunningDetectionRunning(false);
Jim Miller9f0753f2015-03-23 23:59:22 -0700447 for (int i = 0; i < mCallbacks.size(); i++) {
448 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
449 if (cb != null) {
450 cb.onFingerprintError(msgId, errString);
Jim Millerf41fc962014-06-18 16:33:51 -0700451 }
452 }
453 }
454
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700455 private void setFingerprintRunningDetectionRunning(boolean running) {
456 if (running != mFingerprintDetectionRunning) {
457 mFingerprintDetectionRunning = running;
458 notifyFingerprintRunningStateChanged();
459 }
460 }
461
462 private void notifyFingerprintRunningStateChanged() {
463 for (int i = 0; i < mCallbacks.size(); i++) {
464 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
465 if (cb != null) {
466 cb.onFingerprintRunningStateChanged(mFingerprintDetectionRunning);
467 }
468 }
469 }
Adrian Roos4a410172014-08-20 17:41:44 +0200470 private void handleFaceUnlockStateChanged(boolean running, int userId) {
471 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200472 for (int i = 0; i < mCallbacks.size(); i++) {
473 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
474 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200475 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200476 }
477 }
478 }
479
Adrian Roos4a410172014-08-20 17:41:44 +0200480 public boolean isFaceUnlockRunning(int userId) {
481 return mUserFaceUnlockRunning.get(userId);
482 }
483
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700484 public boolean isFingerprintDetectionRunning() {
485 return mFingerprintDetectionRunning;
486 }
487
Jim Miller50e62182014-04-23 17:25:00 -0700488 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100489 // Don't allow trust agent if device is secured with a SIM PIN. This is here
490 // mainly because there's no other way to prompt the user to enter their SIM PIN
491 // once they get past the keyguard screen.
492 final boolean disabledBySimPin = isSimPinSecure();
493 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700494 }
495
Jim Miller06e34502014-07-17 14:46:05 -0700496 private boolean isFingerprintDisabled(int userId) {
497 final DevicePolicyManager dpm =
498 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
499 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
500 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0;
501 }
502
Selim Cineke8bae622015-07-15 13:24:06 -0700503 public boolean getUserCanSkipBouncer(int userId) {
Selim Cinek1fcafc42015-07-20 14:39:25 -0700504 return getUserHasTrust(userId) || (mUserFingerprintAuthenticated.get(userId)
505 && isUnlockingWithFingerprintAllowed());
Selim Cineke8bae622015-07-15 13:24:06 -0700506 }
507
Adrian Roos46842d92014-03-27 14:58:03 +0100508 public boolean getUserHasTrust(int userId) {
Selim Cineke8bae622015-07-15 13:24:06 -0700509 return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100510 }
511
Adrian Roos7861c662014-07-25 15:37:28 +0200512 public boolean getUserTrustIsManaged(int userId) {
513 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
514 }
515
Selim Cinek1fcafc42015-07-20 14:39:25 -0700516 public boolean isUnlockingWithFingerprintAllowed() {
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700517 return mUserHasAuthenticatedSinceBoot && !hasFingerprintUnlockTimedOut(sCurrentUser);
518 }
519
520 /**
521 * @return true if the user hasn't use strong authentication (pattern, PIN, password) since a
522 * while and thus can't unlock with fingerprint, false otherwise
523 */
524 public boolean hasFingerprintUnlockTimedOut(int userId) {
525 return mStrongAuthTimedOut.contains(userId);
526 }
527
528 public void reportSuccessfulStrongAuthUnlockAttempt() {
529 mStrongAuthTimedOut.remove(sCurrentUser);
530 scheduleStrongAuthTimeout();
Jim Millere0507bb2015-08-12 20:30:34 -0700531 if (mFpm != null) {
532 byte[] token = null; /* TODO: pass real auth token once fp HAL supports it */
533 mFpm.resetTimeout(token);
534 }
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700535 }
536
537 private void scheduleStrongAuthTimeout() {
538 long when = SystemClock.elapsedRealtime() + FINGERPRINT_UNLOCK_TIMEOUT_MS;
539 Intent intent = new Intent(ACTION_STRONG_AUTH_TIMEOUT);
540 intent.putExtra(USER_ID, sCurrentUser);
541 PendingIntent sender = PendingIntent.getBroadcast(mContext,
542 sCurrentUser, intent, PendingIntent.FLAG_CANCEL_CURRENT);
543 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, sender);
544 notifyStrongAuthTimedOutChanged(sCurrentUser);
545 }
546
547 private void notifyStrongAuthTimedOutChanged(int userId) {
548 for (int i = 0; i < mCallbacks.size(); i++) {
549 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
550 if (cb != null) {
551 cb.onStrongAuthTimeoutExpiredChanged(userId);
552 }
553 }
Selim Cinek1fcafc42015-07-20 14:39:25 -0700554 }
555
Jim Miller8f09fd22013-03-14 19:04:28 -0700556 static class DisplayClientState {
557 public int clientGeneration;
558 public boolean clearing;
559 public PendingIntent intent;
560 public int playbackState;
561 public long playbackEventTime;
562 }
563
564 private DisplayClientState mDisplayClientState = new DisplayClientState();
565
Jim Millerbbf1a742012-07-17 18:30:30 -0700566 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
567
568 public void onReceive(Context context, Intent intent) {
569 final String action = intent.getAction();
570 if (DEBUG) Log.d(TAG, "received broadcast " + action);
571
572 if (Intent.ACTION_TIME_TICK.equals(action)
573 || Intent.ACTION_TIME_CHANGED.equals(action)
Adrian Roos48c796c2014-09-01 14:59:23 +0200574 || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700575 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Jim Millerbbf1a742012-07-17 18:30:30 -0700576 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
577 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
578 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
579 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
580 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
Adrian Roos7b043112015-07-10 13:00:33 -0700581 final int maxChargingCurrent = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700582 final Message msg = mHandler.obtainMessage(
Adrian Roos7b043112015-07-10 13:00:33 -0700583 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
584 maxChargingCurrent));
Jim Millerbbf1a742012-07-17 18:30:30 -0700585 mHandler.sendMessage(msg);
586 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Jim Miller52a61332014-11-12 19:29:51 -0800587 SimData args = SimData.fromIntent(intent);
Jim Millerbbf1a742012-07-17 18:30:30 -0700588 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -0800589 Log.v(TAG, "action " + action
590 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
591 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -0700592 }
Jim Miller52a61332014-11-12 19:29:51 -0800593 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
594 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -0700595 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
596 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
597 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
598 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
599 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
600 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Jason Monk052082c2015-06-11 11:35:23 -0400601 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
602 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800603 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700604 dispatchBootCompleted();
Etan Cohen47051d82015-07-06 16:19:04 -0700605 } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
606 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
607 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
608 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
609 if (DEBUG) {
610 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
611 + subId);
612 }
613 mHandler.sendMessage(
614 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
Jim Millerbbf1a742012-07-17 18:30:30 -0700615 }
616 }
617 };
Jim Miller2de5ee82012-06-14 22:22:50 -0700618
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700619 private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
620
621 public void onReceive(Context context, Intent intent) {
622 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +0200623 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
624 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
625 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700626 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
627 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +0200628 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
629 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
630 getSendingUserId()));
631 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
632 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
633 getSendingUserId()));
634 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
635 .equals(action)) {
636 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700637 }
638 }
639 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700640
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700641 private final BroadcastReceiver mStrongAuthTimeoutReceiver = new BroadcastReceiver() {
642 @Override
643 public void onReceive(Context context, Intent intent) {
644 if (ACTION_STRONG_AUTH_TIMEOUT.equals(intent.getAction())) {
645 int userId = intent.getIntExtra(USER_ID, -1);
646 mStrongAuthTimedOut.add(userId);
647 notifyStrongAuthTimedOutChanged(userId);
648 }
649 }
650 };
651
Jim Miller9f0753f2015-03-23 23:59:22 -0700652 private FingerprintManager.AuthenticationCallback mAuthenticationCallback
653 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -0700654
655 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -0700656 public void onAuthenticationFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700657 handleFingerprintAuthFailed();
Jim Millerce7eb6d2015-04-03 19:29:13 -0700658 };
659
660 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700661 public void onAuthenticationSucceeded(AuthenticationResult result) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700662 handleFingerprintAuthenticated();
Jim Millerf41fc962014-06-18 16:33:51 -0700663 }
664
665 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700666 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700667 handleFingerprintHelp(helpMsgId, helpString.toString());
Jim Miller9f0753f2015-03-23 23:59:22 -0700668 }
669
670 @Override
671 public void onAuthenticationError(int errMsgId, CharSequence errString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700672 handleFingerprintError(errMsgId, errString.toString());
673 }
674
675 @Override
676 public void onAuthenticationAcquired(int acquireInfo) {
677 handleFingerprintAcquired(acquireInfo);
Jim Millerf41fc962014-06-18 16:33:51 -0700678 }
679 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700680 private CancellationSignal mFingerprintCancelSignal;
681 private FingerprintManager mFpm;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700682
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800683 /**
Jim Miller47088bb2009-11-24 00:40:16 -0800684 * When we receive a
685 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -0700686 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800687 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -0800688 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800689 */
Jim Miller52a61332014-11-12 19:29:51 -0800690 private static class SimData {
691 public State simState;
692 public int slotId;
693 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800694
Jim Miller52a61332014-11-12 19:29:51 -0800695 SimData(State state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -0800696 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -0800697 slotId = slot;
698 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -0800699 }
700
Jim Miller52a61332014-11-12 19:29:51 -0800701 static SimData fromIntent(Intent intent) {
702 State state;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800703 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
704 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
705 }
Wink Savillea639b312012-07-10 12:37:54 -0700706 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
Jim Miller52a61332014-11-12 19:29:51 -0800707 int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0);
708 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
Wink Savilled09c4ca2014-11-22 10:08:16 -0800709 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea639b312012-07-10 12:37:54 -0700710 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -0700711 final String absentReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700712 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -0700713
Wink Savillea639b312012-07-10 12:37:54 -0700714 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -0700715 absentReason)) {
Wink Savillea639b312012-07-10 12:37:54 -0700716 state = IccCardConstants.State.PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -0700717 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700718 state = IccCardConstants.State.ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -0700719 }
Wink Savillea639b312012-07-10 12:37:54 -0700720 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
721 state = IccCardConstants.State.READY;
722 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800723 final String lockedReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700724 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
725 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
726 state = IccCardConstants.State.PIN_REQUIRED;
727 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
728 state = IccCardConstants.State.PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800729 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700730 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800731 }
Wink Savillea639b312012-07-10 12:37:54 -0700732 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
733 state = IccCardConstants.State.NETWORK_LOCKED;
Jim Miller109f1fd2012-09-19 20:44:16 -0700734 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
735 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
736 // This is required because telephony doesn't return to "READY" after
737 // these state transitions. See bug 7197471.
738 state = IccCardConstants.State.READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800739 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700740 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800741 }
Jim Miller52a61332014-11-12 19:29:51 -0800742 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800743 }
744
745 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -0800746 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800747 }
748 }
749
Adrian Roos12c1ef52014-06-04 13:54:08 +0200750 public static class BatteryStatus {
Adrian Roos7b043112015-07-10 13:00:33 -0700751 public static final int CHARGING_UNKNOWN = -1;
752 public static final int CHARGING_SLOWLY = 0;
753 public static final int CHARGING_REGULAR = 1;
754 public static final int CHARGING_FAST = 2;
755
Jim Miller16464b82011-10-20 21:10:13 -0700756 public final int status;
757 public final int level;
758 public final int plugged;
759 public final int health;
Adrian Roos7b043112015-07-10 13:00:33 -0700760 public final int maxChargingCurrent;
761 public BatteryStatus(int status, int level, int plugged, int health, int maxChargingCurrent) {
Jim Miller16464b82011-10-20 21:10:13 -0700762 this.status = status;
763 this.level = level;
764 this.plugged = plugged;
765 this.health = health;
Adrian Roos7b043112015-07-10 13:00:33 -0700766 this.maxChargingCurrent = maxChargingCurrent;
Jim Miller16464b82011-10-20 21:10:13 -0700767 }
768
Jim Millerbbf1a742012-07-17 18:30:30 -0700769 /**
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700770 * Determine whether the device is plugged in (USB, power, or wireless).
Jim Millerbbf1a742012-07-17 18:30:30 -0700771 * @return true if the device is plugged in.
772 */
Adrian Roosad3bc7f2014-10-30 18:29:38 +0100773 public boolean isPluggedIn() {
Jim Millerbbf1a742012-07-17 18:30:30 -0700774 return plugged == BatteryManager.BATTERY_PLUGGED_AC
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700775 || plugged == BatteryManager.BATTERY_PLUGGED_USB
776 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Jim Millerbbf1a742012-07-17 18:30:30 -0700777 }
778
779 /**
780 * Whether or not the device is charged. Note that some devices never return 100% for
781 * battery level, so this allows either battery level or status to determine if the
782 * battery is charged.
783 * @return true if the device is charged
784 */
785 public boolean isCharged() {
786 return status == BATTERY_STATUS_FULL || level >= 100;
787 }
788
789 /**
790 * Whether battery is low and needs to be charged.
791 * @return true if battery is low
792 */
793 public boolean isBatteryLow() {
794 return level < LOW_BATTERY_THRESHOLD;
795 }
796
Adrian Roos7b043112015-07-10 13:00:33 -0700797 public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
798 return maxChargingCurrent <= 0 ? CHARGING_UNKNOWN :
799 maxChargingCurrent < slowThreshold ? CHARGING_SLOWLY :
800 maxChargingCurrent > fastThreshold ? CHARGING_FAST :
801 CHARGING_REGULAR;
802 }
Jim Miller16464b82011-10-20 21:10:13 -0700803 }
804
Jim Millerdcb3d842012-08-23 19:18:12 -0700805 public static KeyguardUpdateMonitor getInstance(Context context) {
806 if (sInstance == null) {
807 sInstance = new KeyguardUpdateMonitor(context);
808 }
809 return sInstance;
810 }
811
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700812 protected void handleStartedWakingUp() {
Jorim Jaggi864e64b2015-05-20 14:13:23 -0700813 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -0700814 final int count = mCallbacks.size();
815 for (int i = 0; i < count; i++) {
816 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
817 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700818 cb.onStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -0700819 }
820 }
821 }
822
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700823 protected void handleFinishedGoingToSleep(int arg1) {
Jim Millerf41fc962014-06-18 16:33:51 -0700824 clearFingerprintRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -0700825 final int count = mCallbacks.size();
826 for (int i = 0; i < count; i++) {
827 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
828 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700829 cb.onFinishedGoingToSleep(arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700830 }
831 }
Jorim Jaggi71448a72015-08-18 19:49:04 -0700832 mFingerprintAlreadyAuthenticated = false;
Jorim Jaggiea657062015-04-28 13:45:11 -0700833 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -0700834 }
835
Jorim Jaggif1518da2015-07-30 11:56:36 -0700836 private void handleScreenTurnedOn() {
837 final int count = mCallbacks.size();
838 for (int i = 0; i < count; i++) {
839 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
840 if (cb != null) {
841 cb.onScreenTurnedOn();
842 }
843 }
844 }
845
846 private void handleScreenTurnedOff() {
847 final int count = mCallbacks.size();
848 for (int i = 0; i < count; i++) {
849 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
850 if (cb != null) {
851 cb.onScreenTurnedOff();
852 }
853 }
854 }
855
Adam Powell43a372f2013-09-27 17:43:53 -0700856 /**
857 * IMPORTANT: Must be called from UI thread.
858 */
859 public void dispatchSetBackground(Bitmap bmp) {
860 if (DEBUG) Log.d(TAG, "dispatchSetBackground");
861 final int count = mCallbacks.size();
862 for (int i = 0; i < count; i++) {
863 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
864 if (cb != null) {
865 cb.onSetBackground(bmp);
866 }
867 }
868 }
869
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700870 private void handleUserInfoChanged(int userId) {
871 for (int i = 0; i < mCallbacks.size(); i++) {
872 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
873 if (cb != null) {
874 cb.onUserInfoChanged(userId);
875 }
876 }
877 }
878
Jim Millerdcb3d842012-08-23 19:18:12 -0700879 private KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800880 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800881 mSubscriptionManager = SubscriptionManager.from(context);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700882 mAlarmManager = context.getSystemService(AlarmManager.class);
Michael Jurkafff56142012-11-28 16:51:00 -0800883 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700884
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800885 // Since device can't be un-provisioned, we only need to register a content observer
886 // to update mDeviceProvisioned when we are...
887 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700888 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800889 }
Jim Miller47088bb2009-11-24 00:40:16 -0800890
Jim Millerbbf1a742012-07-17 18:30:30 -0700891 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Adrian Roos7b043112015-07-10 13:00:33 -0700892 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800893
Jim Millerbbf1a742012-07-17 18:30:30 -0700894 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800895 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800896 filter.addAction(Intent.ACTION_TIME_TICK);
897 filter.addAction(Intent.ACTION_TIME_CHANGED);
898 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
899 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Jason Monk052082c2015-06-11 11:35:23 -0400900 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800901 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Etan Cohen47051d82015-07-06 16:19:04 -0700902 filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -0800903 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -0800904 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Jim Millerbbf1a742012-07-17 18:30:30 -0700905 context.registerReceiver(mBroadcastReceiver, filter);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700906
Adam Cohenc276e822012-11-08 13:01:08 -0800907 final IntentFilter bootCompleteFilter = new IntentFilter();
908 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
909 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
910 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter);
911
Adrian Roos48c796c2014-09-01 14:59:23 +0200912 final IntentFilter allUserFilter = new IntentFilter();
913 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
914 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
915 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
916 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
917 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
918 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700919 null, null);
920
Wink Saville071743f2015-01-12 17:11:04 -0800921 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700922 try {
923 ActivityManagerNative.getDefault().registerUserSwitchObserver(
924 new IUserSwitchObserver.Stub() {
925 @Override
926 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -0500927 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700928 newUserId, 0, reply));
929 }
930 @Override
931 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -0500932 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +0200933 newUserId, 0));
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700934 }
Kenny Guy42979622015-04-13 18:03:05 +0000935 @Override
936 public void onForegroundProfileSwitch(int newProfileId) {
937 // Ignore.
938 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700939 });
940 } catch (RemoteException e) {
941 // TODO Auto-generated catch block
942 e.printStackTrace();
943 }
Adrian Roos46842d92014-03-27 14:58:03 +0100944
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700945 IntentFilter strongAuthTimeoutFilter = new IntentFilter();
946 strongAuthTimeoutFilter.addAction(ACTION_STRONG_AUTH_TIMEOUT);
947 context.registerReceiver(mStrongAuthTimeoutReceiver, strongAuthTimeoutFilter,
948 PERMISSION_SELF, null /* handler */);
Jorim Jaggi237b0612015-05-01 14:28:49 -0700949 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
950 mTrustManager.registerTrustListener(this);
Jim Millerf41fc962014-06-18 16:33:51 -0700951
Jim Miller9f0753f2015-03-23 23:59:22 -0700952 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
Jorim Jaggiea657062015-04-28 13:45:11 -0700953 updateFingerprintListeningState();
954 }
955
956 private void updateFingerprintListeningState() {
957 boolean shouldListenForFingerprint = shouldListenForFingerprint();
958 if (mFingerprintDetectionRunning && !shouldListenForFingerprint) {
959 stopListeningForFingerprint();
960 } else if (!mFingerprintDetectionRunning && shouldListenForFingerprint) {
961 startListeningForFingerprint();
962 }
963 }
964
965 private boolean shouldListenForFingerprint() {
Jorim Jaggi71448a72015-08-18 19:49:04 -0700966 return (mKeyguardIsVisible || !mDeviceInteractive) && !mSwitchingUser
967 && !mFingerprintAlreadyAuthenticated;
Jim Miller9f0753f2015-03-23 23:59:22 -0700968 }
969
Jim Millerce7eb6d2015-04-03 19:29:13 -0700970 private void startListeningForFingerprint() {
971 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -0700972 int userId = ActivityManager.getCurrentUser();
Jorim Jaggi71448a72015-08-18 19:49:04 -0700973 if (isUnlockWithFingerprintPossible(userId)) {
Selim Cinek1fcafc42015-07-20 14:39:25 -0700974 mUserHasAuthenticatedSinceBoot = mTrustManager.hasUserAuthenticatedSinceBoot(
975 ActivityManager.getCurrentUser());
Jim Millerce7eb6d2015-04-03 19:29:13 -0700976 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700977 mFingerprintCancelSignal.cancel();
978 }
Jim Millerce7eb6d2015-04-03 19:29:13 -0700979 mFingerprintCancelSignal = new CancellationSignal();
Jim Millerf501b582015-06-03 16:36:31 -0700980 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null, userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700981 setFingerprintRunningDetectionRunning(true);
Jim Miller9f0753f2015-03-23 23:59:22 -0700982 }
983 }
984
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700985 public boolean isUnlockWithFingerprintPossible(int userId) {
Selim Cinek3122fa82015-06-18 01:38:59 -0700986 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
987 && mFpm.getEnrolledFingerprints(userId).size() > 0;
988 }
989
Jorim Jaggiea657062015-04-28 13:45:11 -0700990 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -0700991 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
992 if (isFingerprintDetectionRunning()) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700993 mFingerprintCancelSignal.cancel();
Jim Millerce7eb6d2015-04-03 19:29:13 -0700994 mFingerprintCancelSignal = null;
Jim Miller9f0753f2015-03-23 23:59:22 -0700995 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700996 setFingerprintRunningDetectionRunning(false);
Jim Millerbbf1a742012-07-17 18:30:30 -0700997 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800998
Michael Jurkafff56142012-11-28 16:51:00 -0800999 private boolean isDeviceProvisionedInSettingsDb() {
1000 return Settings.Global.getInt(mContext.getContentResolver(),
1001 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1002 }
1003
Jim Millerbbf1a742012-07-17 18:30:30 -07001004 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -08001005 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001006 @Override
1007 public void onChange(boolean selfChange) {
1008 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -08001009 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001010 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001011 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001012 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001013 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001014 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001015 };
1016
1017 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -07001018 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -08001019 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -07001020
1021 // prevent a race condition between where we check the flag and where we register the
1022 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -08001023 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001024 if (provisioned != mDeviceProvisioned) {
1025 mDeviceProvisioned = provisioned;
1026 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001027 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001028 }
1029 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001030 }
1031
Jim Millerbbf1a742012-07-17 18:30:30 -07001032 /**
1033 * Handle {@link #MSG_DPM_STATE_CHANGED}
1034 */
Jim Millerb0304762012-03-13 20:01:25 -07001035 protected void handleDevicePolicyManagerStateChanged() {
Jim Millerdcb3d842012-08-23 19:18:12 -07001036 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1037 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1038 if (cb != null) {
1039 cb.onDevicePolicyManagerStateChanged();
1040 }
Jim Millerb0304762012-03-13 20:01:25 -07001041 }
1042 }
1043
Jim Millerbbf1a742012-07-17 18:30:30 -07001044 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001045 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -07001046 */
Chris Wrenf41c61b2012-11-29 15:19:54 -05001047 protected void handleUserSwitching(int userId, IRemoteCallback reply) {
Jorim Jaggiaa4d32a2015-05-13 16:30:04 -07001048 mSwitchingUser = true;
1049 updateFingerprintListeningState();
1050
Jim Millerbbf1a742012-07-17 18:30:30 -07001051 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001052 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1053 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001054 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -07001055 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001056 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001057 try {
1058 reply.sendResult(null);
1059 } catch (RemoteException e) {
1060 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001061 }
1062
Jim Millerbbf1a742012-07-17 18:30:30 -07001063 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001064 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
1065 */
1066 protected void handleUserSwitchComplete(int userId) {
Jorim Jaggiaa4d32a2015-05-13 16:30:04 -07001067 mSwitchingUser = false;
1068 updateFingerprintListeningState();
1069
Chris Wrenf41c61b2012-11-29 15:19:54 -05001070 for (int i = 0; i < mCallbacks.size(); i++) {
1071 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1072 if (cb != null) {
1073 cb.onUserSwitchComplete(userId);
1074 }
1075 }
1076 }
1077
1078 /**
Jim Miller90873d52013-09-26 18:11:38 -07001079 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
1080 * keyguard crashes sometime after boot, then it will never receive this
1081 * broadcast and hence not handle the event. This method is ultimately called by
1082 * PhoneWindowManager in this case.
1083 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001084 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001085 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -07001086 }
1087
1088 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001089 * Handle {@link #MSG_BOOT_COMPLETED}
1090 */
1091 protected void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001092 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001093 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001094 for (int i = 0; i < mCallbacks.size(); i++) {
1095 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1096 if (cb != null) {
1097 cb.onBootCompleted();
1098 }
1099 }
1100 }
1101
1102 /**
Jim Miller5ecd8112013-01-09 18:50:26 -08001103 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001104 * destroyed.
1105 */
1106 public boolean hasBootCompleted() {
1107 return mBootCompleted;
1108 }
1109
1110 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001111 * Handle {@link #MSG_DEVICE_PROVISIONED}
1112 */
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001113 protected void handleDeviceProvisioned() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001114 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001115 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1116 if (cb != null) {
1117 cb.onDeviceProvisioned();
1118 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001119 }
Michael Jurkafff56142012-11-28 16:51:00 -08001120 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001121 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -08001122 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
1123 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001124 }
1125 }
1126
Jim Millerbbf1a742012-07-17 18:30:30 -07001127 /**
1128 * Handle {@link #MSG_PHONE_STATE_CHANGED}
1129 */
Jim Millerc23024d2010-02-24 15:37:00 -08001130 protected void handlePhoneStateChanged(String newState) {
1131 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001132 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
1133 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
1134 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
1135 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
1136 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
1137 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
1138 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001139 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001140 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1141 if (cb != null) {
1142 cb.onPhoneStateChanged(mPhoneState);
1143 }
Jim Millerc23024d2010-02-24 15:37:00 -08001144 }
1145 }
1146
Jim Millerbbf1a742012-07-17 18:30:30 -07001147 /**
1148 * Handle {@link #MSG_RINGER_MODE_CHANGED}
1149 */
Jim Miller47088bb2009-11-24 00:40:16 -08001150 protected void handleRingerModeChange(int mode) {
1151 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001152 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -07001153 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001154 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1155 if (cb != null) {
1156 cb.onRingerModeChanged(mode);
1157 }
Jim Miller47088bb2009-11-24 00:40:16 -08001158 }
1159 }
1160
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001161 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001162 * Handle {@link #MSG_TIME_UPDATE}
1163 */
1164 private void handleTimeUpdate() {
1165 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001166 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001167 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1168 if (cb != null) {
1169 cb.onTimeChanged();
1170 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001171 }
1172 }
1173
1174 /**
1175 * Handle {@link #MSG_BATTERY_UPDATE}
1176 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001177 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001178 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001179 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
1180 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07001181 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001182 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001183 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1184 if (cb != null) {
1185 cb.onRefreshBatteryInfo(status);
1186 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001187 }
1188 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001189 }
1190
1191 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001192 * Handle {@link #MSG_SIM_STATE_CHANGE}
1193 */
Jim Miller52a61332014-11-12 19:29:51 -08001194 private void handleSimStateChange(int subId, int slotId, State state) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001195
Jim Miller52a61332014-11-12 19:29:51 -08001196 if (DEBUG_SIM_STATES) {
1197 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
1198 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001199 }
1200
Wink Savillea54bf652014-12-11 13:37:50 -08001201 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08001202 Log.w(TAG, "invalid subId in handleSimStateChange()");
1203 return;
1204 }
1205
1206 SimData data = mSimDatas.get(subId);
1207 final boolean changed;
1208 if (data == null) {
1209 data = new SimData(state, slotId, subId);
1210 mSimDatas.put(subId, data);
1211 changed = true; // no data yet; force update
1212 } else {
1213 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
1214 data.simState = state;
1215 data.subId = subId;
1216 data.slotId = slotId;
1217 }
1218 if (changed && state != State.UNKNOWN) {
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) {
Jim Miller52a61332014-11-12 19:29:51 -08001222 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07001223 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001224 }
1225 }
1226 }
1227
Jim Millerbbf1a742012-07-17 18:30:30 -07001228 /**
Etan Cohen47051d82015-07-06 16:19:04 -07001229 * Handle {@link #MSG_SERVICE_STATE_CHANGE}
1230 */
1231 private void handleServiceStateChange(int subId, ServiceState serviceState) {
1232 if (DEBUG) {
1233 Log.d(TAG,
1234 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
1235 }
1236
1237 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1238 Log.w(TAG, "invalid subId in handleServiceStateChange()");
1239 return;
1240 }
1241
1242 mServiceStates.put(subId, serviceState);
1243
1244 for (int j = 0; j < mCallbacks.size(); j++) {
1245 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
1246 if (cb != null) {
1247 cb.onRefreshCarrierInfo();
1248 }
1249 }
1250 }
1251
1252 /**
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001253 * Handle {@link #MSG_KEYGUARD_VISIBILITY_CHANGED}
1254 */
1255 private void handleKeyguardVisibilityChanged(int showing) {
1256 if (DEBUG) Log.d(TAG, "handleKeyguardVisibilityChanged(" + showing + ")");
Danielle Millett5d2404d2012-11-01 00:05:27 -04001257 boolean isShowing = (showing == 1);
1258 mKeyguardIsVisible = isShowing;
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001259 for (int i = 0; i < mCallbacks.size(); i++) {
1260 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1261 if (cb != null) {
John Spurlock385a63d2013-10-30 19:40:48 -04001262 cb.onKeyguardVisibilityChangedRaw(isShowing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001263 }
1264 }
Jorim Jaggi71448a72015-08-18 19:49:04 -07001265 if (!isShowing) {
1266 mFingerprintAlreadyAuthenticated = false;
1267 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001268 updateFingerprintListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001269 }
1270
Brian Colonna7fce3802013-09-17 15:51:32 -04001271 /**
Selim Cinek1fcafc42015-07-20 14:39:25 -07001272 * Handle {@link #MSG_KEYGUARD_RESET}
1273 */
1274 private void handleKeyguardReset() {
1275 if (DEBUG) Log.d(TAG, "handleKeyguardReset");
1276 if (!isUnlockingWithFingerprintAllowed()) {
1277 updateFingerprintListeningState();
1278 }
1279 }
1280
1281 /**
Adrian Roosb6011622014-05-14 15:52:53 +02001282 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
1283 * @see #sendKeyguardBouncerChanged(boolean)
1284 */
1285 private void handleKeyguardBouncerChanged(int bouncer) {
1286 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
1287 boolean isBouncer = (bouncer == 1);
1288 mBouncer = isBouncer;
1289 for (int i = 0; i < mCallbacks.size(); i++) {
1290 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1291 if (cb != null) {
1292 cb.onKeyguardBouncerChanged(isBouncer);
1293 }
1294 }
1295 }
1296
1297 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04001298 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
1299 */
1300 private void handleReportEmergencyCallAction() {
1301 for (int i = 0; i < mCallbacks.size(); i++) {
1302 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1303 if (cb != null) {
1304 cb.onEmergencyCallAction();
1305 }
1306 }
1307 }
1308
Jim Miller16464b82011-10-20 21:10:13 -07001309 private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001310 final boolean nowPluggedIn = current.isPluggedIn();
1311 final boolean wasPluggedIn = old.isPluggedIn();
Jim Miller79a444a2011-02-15 15:02:11 -08001312 final boolean stateChangedWhilePluggedIn =
Jim Miller16464b82011-10-20 21:10:13 -07001313 wasPluggedIn == true && nowPluggedIn == true
1314 && (old.status != current.status);
1315
1316 // change in plug state is always interesting
1317 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001318 return true;
1319 }
1320
1321 // change in battery level while plugged in
Jim Miller16464b82011-10-20 21:10:13 -07001322 if (nowPluggedIn && old.level != current.level) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001323 return true;
1324 }
1325
Jim Miller16464b82011-10-20 21:10:13 -07001326 // change where battery needs charging
Jim Millerbbf1a742012-07-17 18:30:30 -07001327 if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
Jim Miller16464b82011-10-20 21:10:13 -07001328 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001329 }
Adrian Roos76dc5a52015-07-21 16:20:36 -07001330
1331 // change in charging current while plugged in
1332 if (nowPluggedIn && current.maxChargingCurrent != old.maxChargingCurrent) {
1333 return true;
1334 }
1335
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001336 return false;
1337 }
1338
1339 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001340 * Remove the given observer's callback.
1341 *
Jim Miller6212cc02012-09-05 17:35:31 -07001342 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001343 */
Jim Miller6212cc02012-09-05 17:35:31 -07001344 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
1345 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
1346 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1347 if (mCallbacks.get(i).get() == callback) {
1348 mCallbacks.remove(i);
1349 }
1350 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001351 }
1352
1353 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001354 * Register to receive notifications about general keyguard information
1355 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07001356 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001357 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001358 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Jim Miller6212cc02012-09-05 17:35:31 -07001359 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
1360 // Prevent adding duplicate callbacks
1361 for (int i = 0; i < mCallbacks.size(); i++) {
1362 if (mCallbacks.get(i).get() == callback) {
1363 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
1364 new Exception("Called by"));
1365 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07001366 }
1367 }
Jim Miller6212cc02012-09-05 17:35:31 -07001368 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
1369 removeCallback(null); // remove unused references
1370 sendUpdates(callback);
1371 }
1372
1373 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
1374 // Notify listener of the current state
1375 callback.onRefreshBatteryInfo(mBatteryStatus);
1376 callback.onTimeChanged();
1377 callback.onRingerModeChanged(mRingMode);
1378 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05001379 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07001380 callback.onClockVisibilityChanged();
Jim Miller52a61332014-11-12 19:29:51 -08001381 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
1382 final SimData state = data.getValue();
1383 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
1384 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001385 }
1386
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001387 public void sendKeyguardVisibilityChanged(boolean showing) {
1388 if (DEBUG) Log.d(TAG, "sendKeyguardVisibilityChanged(" + showing + ")");
1389 Message message = mHandler.obtainMessage(MSG_KEYGUARD_VISIBILITY_CHANGED);
1390 message.arg1 = showing ? 1 : 0;
1391 message.sendToTarget();
1392 }
1393
Selim Cinek1fcafc42015-07-20 14:39:25 -07001394 public void sendKeyguardReset() {
1395 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
1396 }
1397
Adrian Roosb6011622014-05-14 15:52:53 +02001398 /**
1399 * @see #handleKeyguardBouncerChanged(int)
1400 */
1401 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
1402 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
1403 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
1404 message.arg1 = showingBouncer ? 1 : 0;
1405 message.sendToTarget();
1406 }
1407
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001408 /**
Jim Miller90d5d462011-11-17 16:57:01 -08001409 * 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 -08001410 * have the information earlier than waiting for the intent
1411 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08001412 *
1413 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
1414 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001415 */
Jim Miller52a61332014-11-12 19:29:51 -08001416 public void reportSimUnlocked(int subId) {
1417 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
1418 int slotId = SubscriptionManager.getSlotId(subId);
1419 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001420 }
1421
Brian Colonna7fce3802013-09-17 15:51:32 -04001422 /**
1423 * Report that the emergency call button has been pressed and the emergency dialer is
1424 * about to be displayed.
1425 *
1426 * @param bypassHandler runs immediately.
1427 *
1428 * NOTE: Must be called from UI thread if bypassHandler == true.
1429 */
1430 public void reportEmergencyCallAction(boolean bypassHandler) {
1431 if (!bypassHandler) {
1432 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
1433 } else {
1434 handleReportEmergencyCallAction();
1435 }
1436 }
1437
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001438 /**
1439 * @return Whether the device is provisioned (whether they have gone through
1440 * the setup wizard)
1441 */
1442 public boolean isDeviceProvisioned() {
1443 return mDeviceProvisioned;
1444 }
1445
Jorim Jaggi9f743032015-05-04 15:22:40 -07001446 public void clearFailedUnlockAttempts() {
1447 mFailedAttempts.delete(sCurrentUser);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001448 }
1449
Jorim Jaggi9f743032015-05-04 15:22:40 -07001450 public int getFailedUnlockAttempts() {
1451 return mFailedAttempts.get(sCurrentUser, 0);
1452 }
1453
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001454 public void reportFailedStrongAuthUnlockAttempt() {
Jorim Jaggi9f743032015-05-04 15:22:40 -07001455 mFailedAttempts.put(sCurrentUser, getFailedUnlockAttempts() + 1);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001456 }
1457
Jim Millerf41fc962014-06-18 16:33:51 -07001458 public void clearFingerprintRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07001459 mUserFingerprintAuthenticated.clear();
Jim Millerf41fc962014-06-18 16:33:51 -07001460 }
1461
Jim Miller52a61332014-11-12 19:29:51 -08001462 public boolean isSimPinVoiceSecure() {
1463 // TODO: only count SIMs that handle voice
1464 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07001465 }
1466
1467 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08001468 // True if any SIM is pin secure
1469 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
1470 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
1471 }
1472 return false;
1473 }
1474
Jason Monk9ff69bd2014-12-02 16:43:17 -05001475 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08001476 if (mSimDatas.containsKey(subId)) {
1477 return mSimDatas.get(subId).simState;
1478 } else {
1479 return State.UNKNOWN;
1480 }
1481 }
1482
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001483 /**
1484 * @return true if and only if the state has changed for the specified {@code slotId}
1485 */
1486 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08001487
1488 // This is awful. It exists because there are two APIs for getting the SIM status
1489 // that don't return the complete set of values and have different types. In Keyguard we
1490 // need IccCardConstants, but TelephonyManager would only give us
1491 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08001492 final TelephonyManager tele = TelephonyManager.from(mContext);
1493 int simState = tele.getSimState(slotId);
Jim Miller52a61332014-11-12 19:29:51 -08001494 State state;
1495 try {
xinhe18b9c3c2014-12-02 15:03:20 -08001496 state = State.intToState(simState);
Jim Miller52a61332014-11-12 19:29:51 -08001497 } catch(IllegalArgumentException ex) {
xinhe18b9c3c2014-12-02 15:03:20 -08001498 Log.w(TAG, "Unknown sim state: " + simState);
Jim Miller52a61332014-11-12 19:29:51 -08001499 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05001500 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001501 SimData data = mSimDatas.get(subId);
1502 final boolean changed;
1503 if (data == null) {
1504 data = new SimData(state, slotId, subId);
1505 mSimDatas.put(subId, data);
1506 changed = true; // no data yet; force update
1507 } else {
1508 changed = data.simState != state;
1509 data.simState = state;
1510 }
1511 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07001512 }
1513
1514 public static boolean isSimPinSecure(IccCardConstants.State state) {
1515 final IccCardConstants.State simState = state;
1516 return (simState == IccCardConstants.State.PIN_REQUIRED
1517 || simState == IccCardConstants.State.PUK_REQUIRED
1518 || simState == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07001519 }
Jim Miller8f09fd22013-03-14 19:04:28 -07001520
1521 public DisplayClientState getCachedDisplayClientState() {
1522 return mDisplayClientState;
1523 }
Jim Miller20daffd2013-10-07 14:59:53 -07001524
1525 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
1526 // (KeyguardViewMediator, KeyguardHostView)
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001527 public void dispatchStartedWakingUp() {
1528 synchronized (this) {
1529 mDeviceInteractive = true;
1530 }
1531 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
1532 }
1533
1534 public void dispatchFinishedGoingToSleep(int why) {
1535 synchronized(this) {
1536 mDeviceInteractive = false;
1537 }
1538 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
1539 }
1540
Jim Miller20daffd2013-10-07 14:59:53 -07001541 public void dispatchScreenTurnedOn() {
1542 synchronized (this) {
1543 mScreenOn = true;
1544 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001545 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
Jim Miller20daffd2013-10-07 14:59:53 -07001546 }
1547
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001548 public void dispatchScreenTurnedOff() {
Jim Miller20daffd2013-10-07 14:59:53 -07001549 synchronized(this) {
1550 mScreenOn = false;
1551 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001552 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
Jim Miller20daffd2013-10-07 14:59:53 -07001553 }
1554
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001555 public boolean isDeviceInteractive() {
1556 return mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -07001557 }
Jim Miller52a61332014-11-12 19:29:51 -08001558
1559 /**
1560 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
1561 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08001562 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08001563 */
1564 public int getNextSubIdForState(State state) {
1565 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08001566 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08001567 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
1568 for (int i = 0; i < list.size(); i++) {
1569 final SubscriptionInfo info = list.get(i);
1570 final int id = info.getSubscriptionId();
1571 int slotId = SubscriptionManager.getSlotId(id);
1572 if (state == getSimState(id) && bestSlotId > slotId ) {
1573 resultId = id;
1574 bestSlotId = slotId;
1575 }
1576 }
1577 return resultId;
1578 }
1579
1580 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
1581 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
1582 for (int i = 0; i < list.size(); i++) {
1583 SubscriptionInfo info = list.get(i);
1584 if (subId == info.getSubscriptionId()) return info;
1585 }
1586 return null; // not found
1587 }
Jason Monkab525272015-07-13 17:02:49 -04001588
1589 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1590 pw.println("KeyguardUpdateMonitor state:");
1591 pw.println(" SIM States:");
1592 for (SimData data : mSimDatas.values()) {
1593 pw.println(" " + data.toString());
1594 }
1595 pw.println(" Subs:");
1596 if (mSubscriptionInfo != null) {
1597 for (int i = 0; i < mSubscriptionInfo.size(); i++) {
1598 pw.println(" " + mSubscriptionInfo.get(i));
1599 }
1600 }
1601 pw.println(" Service states:");
1602 for (int subId : mServiceStates.keySet()) {
1603 pw.println(" " + subId + "=" + mServiceStates.get(subId));
1604 }
1605 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001606}