blob: 8b220d4d63df573e2bad45b81fb5db8c70ce8ae1 [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 Jaggie8fde5d2016-06-30 23:41:37 -070019import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
20import static android.os.BatteryManager.BATTERY_STATUS_FULL;
21import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
22import static android.os.BatteryManager.EXTRA_HEALTH;
23import static android.os.BatteryManager.EXTRA_LEVEL;
24import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
25import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
26import static android.os.BatteryManager.EXTRA_PLUGGED;
27import static android.os.BatteryManager.EXTRA_STATUS;
28
Jorim Jaggiccdfa932015-04-13 16:29:48 -070029import android.app.ActivityManager;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070030import android.app.ActivityManagerNative;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020031import android.app.AlarmManager;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070032import android.app.IUserSwitchObserver;
Jim Miller8f09fd22013-03-14 19:04:28 -070033import android.app.PendingIntent;
Jim Millerb0304762012-03-13 20:01:25 -070034import android.app.admin.DevicePolicyManager;
Adrian Roos46842d92014-03-27 14:58:03 +010035import android.app.trust.TrustManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080036import android.content.BroadcastReceiver;
Jorim Jaggi031f7952016-09-01 16:39:26 -070037import android.content.ComponentName;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080038import android.content.Context;
39import android.content.Intent;
40import android.content.IntentFilter;
Jorim Jaggi031f7952016-09-01 16:39:26 -070041import android.content.pm.PackageManager;
42import android.content.pm.ResolveInfo;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080043import android.database.ContentObserver;
Jim Miller8f09fd22013-03-14 19:04:28 -070044import android.graphics.Bitmap;
Jorim Jaggi86bed402015-08-20 18:20:02 -070045import android.hardware.fingerprint.FingerprintManager;
46import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
47import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
Jim Miller47088bb2009-11-24 00:40:16 -080048import android.media.AudioManager;
Jim Miller79a444a2011-02-15 15:02:11 -080049import android.os.BatteryManager;
Jim Miller9f0753f2015-03-23 23:59:22 -070050import android.os.CancellationSignal;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080051import android.os.Handler;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070052import android.os.IRemoteCallback;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080053import android.os.Message;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070054import android.os.RemoteException;
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -070055import android.os.SystemClock;
Nick Desaulniers1d396752016-07-25 15:05:33 -070056import android.os.Trace;
Amith Yamasanie8e93a12013-05-09 18:12:30 -070057import android.os.UserHandle;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070058import android.os.UserManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080059import android.provider.Settings;
Etan Cohen47051d82015-07-06 16:19:04 -070060import android.telephony.ServiceState;
Jim Miller52a61332014-11-12 19:29:51 -080061import android.telephony.SubscriptionInfo;
Jim Miller52a61332014-11-12 19:29:51 -080062import android.telephony.SubscriptionManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -080063import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Jim Millerc23024d2010-02-24 15:37:00 -080064import android.telephony.TelephonyManager;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -070065import android.util.ArraySet;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080066import android.util.Log;
Adrian Roos46842d92014-03-27 14:58:03 +010067import android.util.SparseBooleanArray;
Jorim Jaggi9f743032015-05-04 15:22:40 -070068import android.util.SparseIntArray;
Adrian Roos46842d92014-03-27 14:58:03 +010069
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080070import com.google.android.collect.Lists;
71
Jorim Jaggi86bed402015-08-20 18:20:02 -070072import com.android.internal.telephony.IccCardConstants;
73import com.android.internal.telephony.IccCardConstants.State;
74import com.android.internal.telephony.PhoneConstants;
75import com.android.internal.telephony.TelephonyIntents;
Adrian Roosb5e47222015-08-14 15:53:06 -070076import com.android.internal.widget.LockPatternUtils;
Jorim Jaggi86bed402015-08-20 18:20:02 -070077
Jason Monkab525272015-07-13 17:02:49 -040078import java.io.FileDescriptor;
79import java.io.PrintWriter;
Jim Millerdcb3d842012-08-23 19:18:12 -070080import java.lang.ref.WeakReference;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080081import java.util.ArrayList;
Jim Miller52a61332014-11-12 19:29:51 -080082import java.util.HashMap;
83import java.util.List;
84import java.util.Map.Entry;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080085
86/**
87 * Watches for updates that may be interesting to the keyguard, and provides
88 * the up to date information as well as a registration for callbacks that care
89 * to be updated.
90 *
91 * Note: under time crunch, this has been extended to include some stuff that
92 * doesn't really belong here. see {@link #handleBatteryUpdate} where it shutdowns
Jim Miller258341c2012-08-30 16:50:10 -070093 * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()}
94 * and {@link #clearFailedUnlockAttempts()}. Maybe we should rename this 'KeyguardContext'...
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080095 */
Adrian Roos46842d92014-03-27 14:58:03 +010096public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080097
Jim Millerbbf1a742012-07-17 18:30:30 -070098 private static final String TAG = "KeyguardUpdateMonitor";
Jorim Jaggi5cf17872014-03-26 18:31:48 +010099 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller52a61332014-11-12 19:29:51 -0800100 private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
Jim Millerbbf1a742012-07-17 18:30:30 -0700101 private static final int LOW_BATTERY_THRESHOLD = 20;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800102
Jorim Jaggie7b12522014-08-06 16:41:21 +0200103 private static final String ACTION_FACE_UNLOCK_STARTED
104 = "com.android.facelock.FACE_UNLOCK_STARTED";
105 private static final String ACTION_FACE_UNLOCK_STOPPED
106 = "com.android.facelock.FACE_UNLOCK_STOPPED";
107
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700108 private static final String ACTION_STRONG_AUTH_TIMEOUT =
109 "com.android.systemui.ACTION_STRONG_AUTH_TIMEOUT";
110 private static final String USER_ID = "com.android.systemui.USER_ID";
111
112 private static final String PERMISSION_SELF = "com.android.systemui.permission.SELF";
113
Jim Millerbbf1a742012-07-17 18:30:30 -0700114 // Callback messages
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800115 private static final int MSG_TIME_UPDATE = 301;
116 private static final int MSG_BATTERY_UPDATE = 302;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800117 private static final int MSG_SIM_STATE_CHANGE = 304;
Jim Miller47088bb2009-11-24 00:40:16 -0800118 private static final int MSG_RINGER_MODE_CHANGED = 305;
Jim Millerc23024d2010-02-24 15:37:00 -0800119 private static final int MSG_PHONE_STATE_CHANGED = 306;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700120 private static final int MSG_DEVICE_PROVISIONED = 308;
Jim Miller57375342012-09-09 15:20:31 -0700121 private static final int MSG_DPM_STATE_CHANGED = 309;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500122 private static final int MSG_USER_SWITCHING = 310;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700123 private static final int MSG_KEYGUARD_RESET = 312;
Jim Millerf41fc962014-06-18 16:33:51 -0700124 private static final int MSG_BOOT_COMPLETED = 313;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500125 private static final int MSG_USER_SWITCH_COMPLETE = 314;
Jim Millerf41fc962014-06-18 16:33:51 -0700126 private static final int MSG_USER_INFO_CHANGED = 317;
127 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700128 private static final int MSG_STARTED_WAKING_UP = 319;
129 private static final int MSG_FINISHED_GOING_TO_SLEEP = 320;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700130 private static final int MSG_STARTED_GOING_TO_SLEEP = 321;
Adrian Roosb6011622014-05-14 15:52:53 +0200131 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700132 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
133 private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
Jason Monk052082c2015-06-11 11:35:23 -0400134 private static final int MSG_AIRPLANE_MODE_CHANGED = 329;
Etan Cohen47051d82015-07-06 16:19:04 -0700135 private static final int MSG_SERVICE_STATE_CHANGE = 330;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700136 private static final int MSG_SCREEN_TURNED_ON = 331;
137 private static final int MSG_SCREEN_TURNED_OFF = 332;
Selim Cinek99415392016-09-09 14:58:41 -0700138 private static final int MSG_DREAMING_STATE_CHANGED = 333;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800139
Jorim Jaggi86bed402015-08-20 18:20:02 -0700140 /** Fingerprint state: Not listening to fingerprint. */
141 private static final int FINGERPRINT_STATE_STOPPED = 0;
142
143 /** Fingerprint state: Listening. */
144 private static final int FINGERPRINT_STATE_RUNNING = 1;
145
146 /**
147 * Fingerprint state: Cancelling and waiting for the confirmation from FingerprintService to
148 * send us the confirmation that cancellation has happened.
149 */
150 private static final int FINGERPRINT_STATE_CANCELLING = 2;
151
152 /**
153 * Fingerprint state: During cancelling we got another request to start listening, so when we
154 * receive the cancellation done signal, we should start listening again.
155 */
156 private static final int FINGERPRINT_STATE_CANCELLING_RESTARTING = 3;
157
Adrian Roos0c859ae2015-11-23 16:47:50 -0800158 private static final int DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT = 5000000;
159
Jorim Jaggi031f7952016-09-01 16:39:26 -0700160 private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName(
161 "com.android.settings", "com.android.settings.FallbackHome");
162
Jim Millerdcb3d842012-08-23 19:18:12 -0700163 private static KeyguardUpdateMonitor sInstance;
164
Jim Millerbbf1a742012-07-17 18:30:30 -0700165 private final Context mContext;
Jim Miller52a61332014-11-12 19:29:51 -0800166 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
Etan Cohen47051d82015-07-06 16:19:04 -0700167 HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700168
Jim Millerbbf1a742012-07-17 18:30:30 -0700169 private int mRingMode;
170 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400171 private boolean mKeyguardIsVisible;
Jorim Jaggi71448a72015-08-18 19:49:04 -0700172
173 /**
174 * If true, fingerprint was already authenticated and we don't need to start listening again
175 * until the Keyguard has been dismissed.
176 */
177 private boolean mFingerprintAlreadyAuthenticated;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700178 private boolean mGoingToSleep;
Adrian Roosb6011622014-05-14 15:52:53 +0200179 private boolean mBouncer;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800180 private boolean mBootCompleted;
Jorim Jaggi031f7952016-09-01 16:39:26 -0700181 private boolean mNeedsSlowUnlockTransition;
Jorim Jaggid11d1a92016-08-16 16:02:32 -0700182 private boolean mHasLockscreenWallpaper;
Jim Millerbbf1a742012-07-17 18:30:30 -0700183
Jim Millerdcb3d842012-08-23 19:18:12 -0700184 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700185 private boolean mDeviceProvisioned;
186
Jim Millerdcb3d842012-08-23 19:18:12 -0700187 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700188 private BatteryStatus mBatteryStatus;
189
Jim Millerdcb3d842012-08-23 19:18:12 -0700190 // Password attempts
Jorim Jaggi9f743032015-05-04 15:22:40 -0700191 private SparseIntArray mFailedAttempts = new SparseIntArray();
Brian Colonnacc4104f2012-10-09 17:50:46 -0400192
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700193 /** Tracks whether strong authentication hasn't been used since quite some time per user. */
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700194 private ArraySet<Integer> mStrongAuthNotTimedOut = new ArraySet<>();
Rakesh Iyera7aa4d62016-01-19 17:27:23 -0800195 private final StrongAuthTracker mStrongAuthTracker;
Jim Millerbbf1a742012-07-17 18:30:30 -0700196
Jim Miller6212cc02012-09-05 17:35:31 -0700197 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700198 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800199 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700200
Brian Colonnaa5239892013-04-15 11:45:40 -0400201 private boolean mSwitchingUser;
202
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700203 private boolean mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -0700204 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800205 private SubscriptionManager mSubscriptionManager;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700206 private AlarmManager mAlarmManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800207 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700208 private TrustManager mTrustManager;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700209 private UserManager mUserManager;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700210 private int mFingerprintRunningState = FINGERPRINT_STATE_STOPPED;
Jim Miller20daffd2013-10-07 14:59:53 -0700211
Jim Millerbbf1a742012-07-17 18:30:30 -0700212 private final Handler mHandler = new Handler() {
213 @Override
214 public void handleMessage(Message msg) {
215 switch (msg.what) {
216 case MSG_TIME_UPDATE:
217 handleTimeUpdate();
218 break;
219 case MSG_BATTERY_UPDATE:
220 handleBatteryUpdate((BatteryStatus) msg.obj);
221 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700222 case MSG_SIM_STATE_CHANGE:
Jim Miller52a61332014-11-12 19:29:51 -0800223 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700224 break;
225 case MSG_RINGER_MODE_CHANGED:
226 handleRingerModeChange(msg.arg1);
227 break;
228 case MSG_PHONE_STATE_CHANGED:
Adrian Roosb6011622014-05-14 15:52:53 +0200229 handlePhoneStateChanged((String) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700230 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700231 case MSG_DEVICE_PROVISIONED:
232 handleDeviceProvisioned();
233 break;
234 case MSG_DPM_STATE_CHANGED:
235 handleDevicePolicyManagerStateChanged();
236 break;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500237 case MSG_USER_SWITCHING:
Adrian Roosb6011622014-05-14 15:52:53 +0200238 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
Chris Wrenf41c61b2012-11-29 15:19:54 -0500239 break;
240 case MSG_USER_SWITCH_COMPLETE:
241 handleUserSwitchComplete(msg.arg1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700242 break;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700243 case MSG_KEYGUARD_RESET:
244 handleKeyguardReset();
245 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200246 case MSG_KEYGUARD_BOUNCER_CHANGED:
247 handleKeyguardBouncerChanged(msg.arg1);
248 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800249 case MSG_BOOT_COMPLETED:
250 handleBootCompleted();
251 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700252 case MSG_USER_INFO_CHANGED:
253 handleUserInfoChanged(msg.arg1);
254 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400255 case MSG_REPORT_EMERGENCY_CALL_ACTION:
256 handleReportEmergencyCallAction();
257 break;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700258 case MSG_STARTED_GOING_TO_SLEEP:
259 handleStartedGoingToSleep(msg.arg1);
260 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700261 case MSG_FINISHED_GOING_TO_SLEEP:
262 handleFinishedGoingToSleep(msg.arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700263 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700264 case MSG_STARTED_WAKING_UP:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700265 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_STARTED_WAKING_UP");
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700266 handleStartedWakingUp();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700267 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -0700268 break;
Jorim Jaggie7b12522014-08-06 16:41:21 +0200269 case MSG_FACE_UNLOCK_STATE_CHANGED:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700270 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_FACE_UNLOCK_STATE_CHANGED");
Adrian Roos4a410172014-08-20 17:41:44 +0200271 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
Nick Desaulniers1d396752016-07-25 15:05:33 -0700272 Trace.endSection();
Jorim Jaggie7b12522014-08-06 16:41:21 +0200273 break;
Jim Miller52a61332014-11-12 19:29:51 -0800274 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
275 handleSimSubscriptionInfoChanged();
276 break;
Jason Monk052082c2015-06-11 11:35:23 -0400277 case MSG_AIRPLANE_MODE_CHANGED:
278 handleAirplaneModeChanged();
279 break;
Etan Cohen47051d82015-07-06 16:19:04 -0700280 case MSG_SERVICE_STATE_CHANGE:
281 handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
282 break;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700283 case MSG_SCREEN_TURNED_ON:
284 handleScreenTurnedOn();
285 break;
286 case MSG_SCREEN_TURNED_OFF:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700287 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_SCREEN_TURNED_ON");
Jorim Jaggif1518da2015-07-30 11:56:36 -0700288 handleScreenTurnedOff();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700289 Trace.endSection();
Jorim Jaggif1518da2015-07-30 11:56:36 -0700290 break;
Selim Cinek99415392016-09-09 14:58:41 -0700291 case MSG_DREAMING_STATE_CHANGED:
292 handleDreamingStateChanged(msg.arg1);
293 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700294 }
295 }
296 };
297
Wink Savilled09c4ca2014-11-22 10:08:16 -0800298 private OnSubscriptionsChangedListener mSubscriptionListener =
299 new OnSubscriptionsChangedListener() {
Jim Miller52a61332014-11-12 19:29:51 -0800300 @Override
Wink Savilled09c4ca2014-11-22 10:08:16 -0800301 public void onSubscriptionsChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800302 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
303 }
304 };
305
Adrian Roos46842d92014-03-27 14:58:03 +0100306 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200307 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Jim Miller9f0753f2015-03-23 23:59:22 -0700308 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200309 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100310
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700311 private static int sCurrentUser;
312
313 public synchronized static void setCurrentUser(int currentUser) {
314 sCurrentUser = currentUser;
315 }
316
317 public synchronized static int getCurrentUser() {
318 return sCurrentUser;
319 }
320
Adrian Roos46842d92014-03-27 14:58:03 +0100321 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700322 public void onTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos46842d92014-03-27 14:58:03 +0100323 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200324 for (int i = 0; i < mCallbacks.size(); i++) {
325 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
326 if (cb != null) {
327 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700328 if (enabled && flags != 0) {
329 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200330 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200331 }
332 }
Adrian Roos46842d92014-03-27 14:58:03 +0100333 }
334
Jim Miller52a61332014-11-12 19:29:51 -0800335 protected void handleSimSubscriptionInfoChanged() {
336 if (DEBUG_SIM_STATES) {
337 Log.v(TAG, "onSubscriptionInfoChanged()");
Wink Savilled09c4ca2014-11-22 10:08:16 -0800338 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
339 if (sil != null) {
340 for (SubscriptionInfo subInfo : sil) {
341 Log.v(TAG, "SubInfo:" + subInfo);
342 }
343 } else {
344 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800345 }
346 }
347 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
348
349 // Hack level over 9000: Because the subscription id is not yet valid when we see the
350 // first update in handleSimStateChange, we need to force refresh all all SIM states
351 // so the subscription id for them is consistent.
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100352 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
Jim Miller52a61332014-11-12 19:29:51 -0800353 for (int i = 0; i < subscriptionInfos.size(); i++) {
354 SubscriptionInfo info = subscriptionInfos.get(i);
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100355 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
356 if (changed) {
357 changedSubscriptions.add(info);
358 }
Jim Miller52a61332014-11-12 19:29:51 -0800359 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100360 for (int i = 0; i < changedSubscriptions.size(); i++) {
361 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800362 for (int j = 0; j < mCallbacks.size(); j++) {
363 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
364 if (cb != null) {
365 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
366 }
367 }
368 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500369 for (int j = 0; j < mCallbacks.size(); j++) {
370 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
371 if (cb != null) {
372 cb.onRefreshCarrierInfo();
373 }
374 }
Jim Miller52a61332014-11-12 19:29:51 -0800375 }
376
Jason Monk052082c2015-06-11 11:35:23 -0400377 private void handleAirplaneModeChanged() {
378 for (int j = 0; j < mCallbacks.size(); j++) {
379 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
380 if (cb != null) {
381 cb.onRefreshCarrierInfo();
382 }
383 }
384 }
385
Wink Savilled09c4ca2014-11-22 10:08:16 -0800386 /** @return List of SubscriptionInfo records, maybe empty but never null */
Adrian Roos316bf542016-08-23 17:53:07 +0200387 public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800388 List<SubscriptionInfo> sil = mSubscriptionInfo;
389 if (sil == null || forceReload) {
390 sil = mSubscriptionManager.getActiveSubscriptionInfoList();
391 }
392 if (sil == null) {
393 // getActiveSubscriptionInfoList was null callers expect an empty list.
394 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
395 } else {
396 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800397 }
398 return mSubscriptionInfo;
399 }
400
Adrian Roos7861c662014-07-25 15:37:28 +0200401 @Override
402 public void onTrustManagedChanged(boolean managed, int userId) {
403 mUserTrustIsManaged.put(userId, managed);
404
405 for (int i = 0; i < mCallbacks.size(); i++) {
406 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
407 if (cb != null) {
408 cb.onTrustManagedChanged(userId);
409 }
410 }
411 }
412
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700413 private void onFingerprintAuthenticated(int userId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700414 Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
Jim Miller9f0753f2015-03-23 23:59:22 -0700415 mUserFingerprintAuthenticated.put(userId, true);
Jorim Jaggi71448a72015-08-18 19:49:04 -0700416
417 // If fingerprint unlocking is allowed, this event will lead to a Keyguard dismiss or to a
418 // wake-up (if Keyguard is not showing), so we don't need to listen until Keyguard is
419 // fully gone.
420 mFingerprintAlreadyAuthenticated = isUnlockingWithFingerprintAllowed();
Jim Millerf41fc962014-06-18 16:33:51 -0700421 for (int i = 0; i < mCallbacks.size(); i++) {
422 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
423 if (cb != null) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700424 cb.onFingerprintAuthenticated(userId);
Jim Millerf41fc962014-06-18 16:33:51 -0700425 }
426 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700427 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700428 }
429
Jim Millerce7eb6d2015-04-03 19:29:13 -0700430 private void handleFingerprintAuthFailed() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700431 for (int i = 0; i < mCallbacks.size(); i++) {
432 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
433 if (cb != null) {
434 cb.onFingerprintAuthFailed();
435 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700436 }
Jim Millerce7eb6d2015-04-03 19:29:13 -0700437 handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized));
438 }
Jim Millerf41fc962014-06-18 16:33:51 -0700439
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700440 private void handleFingerprintAcquired(int acquireInfo) {
441 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
442 return;
443 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700444 for (int i = 0; i < mCallbacks.size(); i++) {
445 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
446 if (cb != null) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700447 cb.onFingerprintAcquired();
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700448 }
449 }
450 }
451
Jim Miller837fa7e2016-08-08 20:16:22 -0700452 private void handleFingerprintAuthenticated(int authUserId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700453 Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
Jim Millerf41fc962014-06-18 16:33:51 -0700454 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700455 final int userId;
456 try {
457 userId = ActivityManagerNative.getDefault().getCurrentUser().id;
458 } catch (RemoteException e) {
459 Log.e(TAG, "Failed to get current user id: ", e);
460 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700461 }
Jim Miller837fa7e2016-08-08 20:16:22 -0700462 if (userId != authUserId) {
463 Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId);
464 return;
465 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700466 if (isFingerprintDisabled(userId)) {
467 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
468 return;
469 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700470 onFingerprintAuthenticated(userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700471 } finally {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700472 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
Jim Millerf41fc962014-06-18 16:33:51 -0700473 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700474 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700475 }
476
Jim Miller9f0753f2015-03-23 23:59:22 -0700477 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700478 for (int i = 0; i < mCallbacks.size(); i++) {
479 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
480 if (cb != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700481 cb.onFingerprintHelp(msgId, helpString);
482 }
483 }
484 }
485
486 private void handleFingerprintError(int msgId, String errString) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700487 if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
488 && mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
489 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
490 startListeningForFingerprint();
491 } else {
492 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
493 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700494 for (int i = 0; i < mCallbacks.size(); i++) {
495 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
496 if (cb != null) {
497 cb.onFingerprintError(msgId, errString);
Jim Millerf41fc962014-06-18 16:33:51 -0700498 }
499 }
500 }
501
Jorim Jaggi3a464782015-08-28 16:59:13 -0700502 private void handleFingerprintLockoutReset() {
503 updateFingerprintListeningState();
504 }
505
Jorim Jaggi86bed402015-08-20 18:20:02 -0700506 private void setFingerprintRunningState(int fingerprintRunningState) {
507 boolean wasRunning = mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
508 boolean isRunning = fingerprintRunningState == FINGERPRINT_STATE_RUNNING;
509 mFingerprintRunningState = fingerprintRunningState;
510
511 // Clients of KeyguardUpdateMonitor don't care about the internal state about the
512 // asynchronousness of the cancel cycle. So only notify them if the actualy running state
513 // has changed.
514 if (wasRunning != isRunning) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700515 notifyFingerprintRunningStateChanged();
516 }
517 }
518
519 private void notifyFingerprintRunningStateChanged() {
520 for (int i = 0; i < mCallbacks.size(); i++) {
521 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
522 if (cb != null) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700523 cb.onFingerprintRunningStateChanged(isFingerprintDetectionRunning());
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700524 }
525 }
526 }
Adrian Roos4a410172014-08-20 17:41:44 +0200527 private void handleFaceUnlockStateChanged(boolean running, int userId) {
528 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200529 for (int i = 0; i < mCallbacks.size(); i++) {
530 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
531 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200532 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200533 }
534 }
535 }
536
Adrian Roos4a410172014-08-20 17:41:44 +0200537 public boolean isFaceUnlockRunning(int userId) {
538 return mUserFaceUnlockRunning.get(userId);
539 }
540
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700541 public boolean isFingerprintDetectionRunning() {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700542 return mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700543 }
544
Jim Miller50e62182014-04-23 17:25:00 -0700545 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100546 // Don't allow trust agent if device is secured with a SIM PIN. This is here
547 // mainly because there's no other way to prompt the user to enter their SIM PIN
548 // once they get past the keyguard screen.
549 final boolean disabledBySimPin = isSimPinSecure();
550 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700551 }
552
Jim Miller06e34502014-07-17 14:46:05 -0700553 private boolean isFingerprintDisabled(int userId) {
554 final DevicePolicyManager dpm =
555 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
556 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
Adrian Roos733b6632015-08-21 14:32:35 -0700557 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0
558 || isSimPinSecure();
Jim Miller06e34502014-07-17 14:46:05 -0700559 }
560
Selim Cineke8bae622015-07-15 13:24:06 -0700561 public boolean getUserCanSkipBouncer(int userId) {
Selim Cinek1fcafc42015-07-20 14:39:25 -0700562 return getUserHasTrust(userId) || (mUserFingerprintAuthenticated.get(userId)
563 && isUnlockingWithFingerprintAllowed());
Selim Cineke8bae622015-07-15 13:24:06 -0700564 }
565
Adrian Roos46842d92014-03-27 14:58:03 +0100566 public boolean getUserHasTrust(int userId) {
Selim Cineke8bae622015-07-15 13:24:06 -0700567 return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100568 }
569
Adrian Roos7861c662014-07-25 15:37:28 +0200570 public boolean getUserTrustIsManaged(int userId) {
571 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
572 }
573
Selim Cinek1fcafc42015-07-20 14:39:25 -0700574 public boolean isUnlockingWithFingerprintAllowed() {
Adrian Roosb5e47222015-08-14 15:53:06 -0700575 return mStrongAuthTracker.isUnlockingWithFingerprintAllowed()
576 && !hasFingerprintUnlockTimedOut(sCurrentUser);
577 }
578
Jorim Jaggi031f7952016-09-01 16:39:26 -0700579 public boolean needsSlowUnlockTransition() {
580 return mNeedsSlowUnlockTransition;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700581 }
582
Adrian Roosb5e47222015-08-14 15:53:06 -0700583 public StrongAuthTracker getStrongAuthTracker() {
584 return mStrongAuthTracker;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700585 }
586
587 /**
588 * @return true if the user hasn't use strong authentication (pattern, PIN, password) since a
589 * while and thus can't unlock with fingerprint, false otherwise
590 */
591 public boolean hasFingerprintUnlockTimedOut(int userId) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700592 return !mStrongAuthNotTimedOut.contains(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700593 }
594
595 public void reportSuccessfulStrongAuthUnlockAttempt() {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700596 mStrongAuthNotTimedOut.add(sCurrentUser);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700597 scheduleStrongAuthTimeout();
Jim Millere0507bb2015-08-12 20:30:34 -0700598 if (mFpm != null) {
599 byte[] token = null; /* TODO: pass real auth token once fp HAL supports it */
600 mFpm.resetTimeout(token);
601 }
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700602 }
603
604 private void scheduleStrongAuthTimeout() {
Michal Karpinski0b72a722016-06-21 15:05:53 +0100605 final DevicePolicyManager dpm =
606 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
607 long when = SystemClock.elapsedRealtime() + dpm.getRequiredStrongAuthTimeout(null,
608 sCurrentUser);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700609 Intent intent = new Intent(ACTION_STRONG_AUTH_TIMEOUT);
610 intent.putExtra(USER_ID, sCurrentUser);
611 PendingIntent sender = PendingIntent.getBroadcast(mContext,
612 sCurrentUser, intent, PendingIntent.FLAG_CANCEL_CURRENT);
613 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, sender);
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700614 notifyStrongAuthStateChanged(sCurrentUser);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700615 }
616
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700617 private void notifyStrongAuthStateChanged(int userId) {
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700618 for (int i = 0; i < mCallbacks.size(); i++) {
619 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
620 if (cb != null) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700621 cb.onStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700622 }
623 }
Selim Cinek1fcafc42015-07-20 14:39:25 -0700624 }
625
Jim Miller8f09fd22013-03-14 19:04:28 -0700626 static class DisplayClientState {
627 public int clientGeneration;
628 public boolean clearing;
629 public PendingIntent intent;
630 public int playbackState;
631 public long playbackEventTime;
632 }
633
634 private DisplayClientState mDisplayClientState = new DisplayClientState();
635
Jim Millerbbf1a742012-07-17 18:30:30 -0700636 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
637
Jim Millerd72d5ac2015-09-29 18:55:32 -0700638 @Override
Jim Millerbbf1a742012-07-17 18:30:30 -0700639 public void onReceive(Context context, Intent intent) {
640 final String action = intent.getAction();
641 if (DEBUG) Log.d(TAG, "received broadcast " + action);
642
643 if (Intent.ACTION_TIME_TICK.equals(action)
644 || Intent.ACTION_TIME_CHANGED.equals(action)
Adrian Roos48c796c2014-09-01 14:59:23 +0200645 || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700646 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Jim Millerbbf1a742012-07-17 18:30:30 -0700647 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
648 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
649 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
650 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
651 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
Adrian Roos0c859ae2015-11-23 16:47:50 -0800652
653 final int maxChargingMicroAmp = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
654 int maxChargingMicroVolt = intent.getIntExtra(EXTRA_MAX_CHARGING_VOLTAGE, -1);
655 final int maxChargingMicroWatt;
656
657 if (maxChargingMicroVolt <= 0) {
658 maxChargingMicroVolt = DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT;
659 }
660 if (maxChargingMicroAmp > 0) {
661 // Calculating muW = muA * muV / (10^6 mu^2 / mu); splitting up the divisor
662 // to maintain precision equally on both factors.
663 maxChargingMicroWatt = (maxChargingMicroAmp / 1000)
664 * (maxChargingMicroVolt / 1000);
665 } else {
666 maxChargingMicroWatt = -1;
667 }
Jim Millerbbf1a742012-07-17 18:30:30 -0700668 final Message msg = mHandler.obtainMessage(
Adrian Roos7b043112015-07-10 13:00:33 -0700669 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
Adrian Roos0c859ae2015-11-23 16:47:50 -0800670 maxChargingMicroWatt));
Jim Millerbbf1a742012-07-17 18:30:30 -0700671 mHandler.sendMessage(msg);
672 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Jim Miller52a61332014-11-12 19:29:51 -0800673 SimData args = SimData.fromIntent(intent);
Jim Millerbbf1a742012-07-17 18:30:30 -0700674 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -0800675 Log.v(TAG, "action " + action
676 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
677 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -0700678 }
Jim Miller52a61332014-11-12 19:29:51 -0800679 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
680 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -0700681 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
682 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
683 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
684 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
685 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
686 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Jason Monk052082c2015-06-11 11:35:23 -0400687 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
688 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800689 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700690 dispatchBootCompleted();
Etan Cohen47051d82015-07-06 16:19:04 -0700691 } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
692 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
693 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
694 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
695 if (DEBUG) {
696 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
697 + subId);
698 }
699 mHandler.sendMessage(
700 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
Jim Millerbbf1a742012-07-17 18:30:30 -0700701 }
702 }
703 };
Jim Miller2de5ee82012-06-14 22:22:50 -0700704
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700705 private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
706
Jim Millerd72d5ac2015-09-29 18:55:32 -0700707 @Override
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700708 public void onReceive(Context context, Intent intent) {
709 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +0200710 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
711 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
712 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700713 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
714 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +0200715 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700716 Trace.beginSection("KeyguardUpdateMonitor.mBroadcastAllReceiver#onReceive ACTION_FACE_UNLOCK_STARTED");
Adrian Roos48c796c2014-09-01 14:59:23 +0200717 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
718 getSendingUserId()));
Nick Desaulniers1d396752016-07-25 15:05:33 -0700719 Trace.endSection();
Adrian Roos48c796c2014-09-01 14:59:23 +0200720 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
721 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
722 getSendingUserId()));
723 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
724 .equals(action)) {
725 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700726 }
727 }
728 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700729
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700730 private final BroadcastReceiver mStrongAuthTimeoutReceiver = new BroadcastReceiver() {
731 @Override
732 public void onReceive(Context context, Intent intent) {
733 if (ACTION_STRONG_AUTH_TIMEOUT.equals(intent.getAction())) {
734 int userId = intent.getIntExtra(USER_ID, -1);
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700735 mStrongAuthNotTimedOut.remove(userId);
736 notifyStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700737 }
738 }
739 };
740
Jorim Jaggi3a464782015-08-28 16:59:13 -0700741 private final FingerprintManager.LockoutResetCallback mLockoutResetCallback
742 = new FingerprintManager.LockoutResetCallback() {
743 @Override
744 public void onLockoutReset() {
745 handleFingerprintLockoutReset();
746 }
747 };
748
Jim Miller9f0753f2015-03-23 23:59:22 -0700749 private FingerprintManager.AuthenticationCallback mAuthenticationCallback
750 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -0700751
752 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -0700753 public void onAuthenticationFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700754 handleFingerprintAuthFailed();
Jim Millerce7eb6d2015-04-03 19:29:13 -0700755 };
756
757 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700758 public void onAuthenticationSucceeded(AuthenticationResult result) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700759 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
Jim Miller837fa7e2016-08-08 20:16:22 -0700760 handleFingerprintAuthenticated(result.getUserId());
Nick Desaulniers1d396752016-07-25 15:05:33 -0700761 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700762 }
763
764 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700765 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700766 handleFingerprintHelp(helpMsgId, helpString.toString());
Jim Miller9f0753f2015-03-23 23:59:22 -0700767 }
768
769 @Override
770 public void onAuthenticationError(int errMsgId, CharSequence errString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700771 handleFingerprintError(errMsgId, errString.toString());
772 }
773
774 @Override
775 public void onAuthenticationAcquired(int acquireInfo) {
776 handleFingerprintAcquired(acquireInfo);
Jim Millerf41fc962014-06-18 16:33:51 -0700777 }
778 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700779 private CancellationSignal mFingerprintCancelSignal;
780 private FingerprintManager mFpm;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700781
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800782 /**
Jim Miller47088bb2009-11-24 00:40:16 -0800783 * When we receive a
784 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -0700785 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800786 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -0800787 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800788 */
Jim Miller52a61332014-11-12 19:29:51 -0800789 private static class SimData {
790 public State simState;
791 public int slotId;
792 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800793
Jim Miller52a61332014-11-12 19:29:51 -0800794 SimData(State state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -0800795 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -0800796 slotId = slot;
797 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -0800798 }
799
Jim Miller52a61332014-11-12 19:29:51 -0800800 static SimData fromIntent(Intent intent) {
801 State state;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800802 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
803 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
804 }
Wink Savillea639b312012-07-10 12:37:54 -0700805 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
Jim Miller52a61332014-11-12 19:29:51 -0800806 int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0);
807 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
Wink Savilled09c4ca2014-11-22 10:08:16 -0800808 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea639b312012-07-10 12:37:54 -0700809 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -0700810 final String absentReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700811 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -0700812
Wink Savillea639b312012-07-10 12:37:54 -0700813 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -0700814 absentReason)) {
Wink Savillea639b312012-07-10 12:37:54 -0700815 state = IccCardConstants.State.PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -0700816 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700817 state = IccCardConstants.State.ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -0700818 }
Wink Savillea639b312012-07-10 12:37:54 -0700819 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
820 state = IccCardConstants.State.READY;
821 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800822 final String lockedReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700823 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
824 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
825 state = IccCardConstants.State.PIN_REQUIRED;
826 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
827 state = IccCardConstants.State.PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800828 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700829 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800830 }
Wink Savillea639b312012-07-10 12:37:54 -0700831 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
832 state = IccCardConstants.State.NETWORK_LOCKED;
Jim Miller109f1fd2012-09-19 20:44:16 -0700833 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
834 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
835 // This is required because telephony doesn't return to "READY" after
836 // these state transitions. See bug 7197471.
837 state = IccCardConstants.State.READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800838 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700839 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800840 }
Jim Miller52a61332014-11-12 19:29:51 -0800841 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800842 }
843
Jim Millerd72d5ac2015-09-29 18:55:32 -0700844 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800845 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -0800846 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800847 }
848 }
849
Adrian Roos12c1ef52014-06-04 13:54:08 +0200850 public static class BatteryStatus {
Adrian Roos7b043112015-07-10 13:00:33 -0700851 public static final int CHARGING_UNKNOWN = -1;
852 public static final int CHARGING_SLOWLY = 0;
853 public static final int CHARGING_REGULAR = 1;
854 public static final int CHARGING_FAST = 2;
855
Jim Miller16464b82011-10-20 21:10:13 -0700856 public final int status;
857 public final int level;
858 public final int plugged;
859 public final int health;
Adrian Roos0c859ae2015-11-23 16:47:50 -0800860 public final int maxChargingWattage;
861 public BatteryStatus(int status, int level, int plugged, int health,
862 int maxChargingWattage) {
Jim Miller16464b82011-10-20 21:10:13 -0700863 this.status = status;
864 this.level = level;
865 this.plugged = plugged;
866 this.health = health;
Adrian Roos0c859ae2015-11-23 16:47:50 -0800867 this.maxChargingWattage = maxChargingWattage;
Jim Miller16464b82011-10-20 21:10:13 -0700868 }
869
Jim Millerbbf1a742012-07-17 18:30:30 -0700870 /**
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700871 * Determine whether the device is plugged in (USB, power, or wireless).
Jim Millerbbf1a742012-07-17 18:30:30 -0700872 * @return true if the device is plugged in.
873 */
Adrian Roosad3bc7f2014-10-30 18:29:38 +0100874 public boolean isPluggedIn() {
Jim Millerbbf1a742012-07-17 18:30:30 -0700875 return plugged == BatteryManager.BATTERY_PLUGGED_AC
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700876 || plugged == BatteryManager.BATTERY_PLUGGED_USB
877 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Jim Millerbbf1a742012-07-17 18:30:30 -0700878 }
879
880 /**
881 * Whether or not the device is charged. Note that some devices never return 100% for
882 * battery level, so this allows either battery level or status to determine if the
883 * battery is charged.
884 * @return true if the device is charged
885 */
886 public boolean isCharged() {
887 return status == BATTERY_STATUS_FULL || level >= 100;
888 }
889
890 /**
891 * Whether battery is low and needs to be charged.
892 * @return true if battery is low
893 */
894 public boolean isBatteryLow() {
895 return level < LOW_BATTERY_THRESHOLD;
896 }
897
Adrian Roos7b043112015-07-10 13:00:33 -0700898 public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
Adrian Roos0c859ae2015-11-23 16:47:50 -0800899 return maxChargingWattage <= 0 ? CHARGING_UNKNOWN :
900 maxChargingWattage < slowThreshold ? CHARGING_SLOWLY :
901 maxChargingWattage > fastThreshold ? CHARGING_FAST :
Adrian Roos7b043112015-07-10 13:00:33 -0700902 CHARGING_REGULAR;
903 }
Jim Miller16464b82011-10-20 21:10:13 -0700904 }
905
Adrian Roosb5e47222015-08-14 15:53:06 -0700906 public class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
Rakesh Iyera7aa4d62016-01-19 17:27:23 -0800907 public StrongAuthTracker(Context context) {
908 super(context);
909 }
Adrian Roosb5e47222015-08-14 15:53:06 -0700910
911 public boolean isUnlockingWithFingerprintAllowed() {
912 int userId = getCurrentUser();
913 return isFingerprintAllowedForUser(userId);
914 }
915
916 public boolean hasUserAuthenticatedSinceBoot() {
917 int userId = getCurrentUser();
918 return (getStrongAuthForUser(userId)
919 & STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
920 }
921
922 @Override
923 public void onStrongAuthRequiredChanged(int userId) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700924 notifyStrongAuthStateChanged(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -0700925 }
926 }
927
Jim Millerdcb3d842012-08-23 19:18:12 -0700928 public static KeyguardUpdateMonitor getInstance(Context context) {
929 if (sInstance == null) {
930 sInstance = new KeyguardUpdateMonitor(context);
931 }
932 return sInstance;
933 }
934
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700935 protected void handleStartedWakingUp() {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700936 Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
Jorim Jaggi864e64b2015-05-20 14:13:23 -0700937 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -0700938 final int count = mCallbacks.size();
939 for (int i = 0; i < count; i++) {
940 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
941 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700942 cb.onStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -0700943 }
944 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700945 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -0700946 }
947
Jorim Jaggi95e40382015-09-16 15:53:42 -0700948 protected void handleStartedGoingToSleep(int arg1) {
Jim Millerf41fc962014-06-18 16:33:51 -0700949 clearFingerprintRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -0700950 final int count = mCallbacks.size();
951 for (int i = 0; i < count; i++) {
952 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
953 if (cb != null) {
Jorim Jaggi95e40382015-09-16 15:53:42 -0700954 cb.onStartedGoingToSleep(arg1);
955 }
956 }
957 mGoingToSleep = true;
958 mFingerprintAlreadyAuthenticated = false;
959 updateFingerprintListeningState();
960 }
961
962 protected void handleFinishedGoingToSleep(int arg1) {
963 mGoingToSleep = false;
964 final int count = mCallbacks.size();
965 for (int i = 0; i < count; i++) {
966 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
967 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700968 cb.onFinishedGoingToSleep(arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700969 }
970 }
Jorim Jaggiea657062015-04-28 13:45:11 -0700971 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -0700972 }
973
Jorim Jaggif1518da2015-07-30 11:56:36 -0700974 private void handleScreenTurnedOn() {
975 final int count = mCallbacks.size();
976 for (int i = 0; i < count; i++) {
977 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
978 if (cb != null) {
979 cb.onScreenTurnedOn();
980 }
981 }
982 }
983
984 private void handleScreenTurnedOff() {
985 final int count = mCallbacks.size();
986 for (int i = 0; i < count; i++) {
987 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
988 if (cb != null) {
989 cb.onScreenTurnedOff();
990 }
991 }
992 }
993
Selim Cinek99415392016-09-09 14:58:41 -0700994 private void handleDreamingStateChanged(int dreamStart) {
995 final int count = mCallbacks.size();
996 boolean showingDream = dreamStart == 1;
997 for (int i = 0; i < count; i++) {
998 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
999 if (cb != null) {
1000 cb.onDreamingStateChanged(showingDream);
1001 }
1002 }
1003 }
1004
Adam Powell43a372f2013-09-27 17:43:53 -07001005 /**
1006 * IMPORTANT: Must be called from UI thread.
1007 */
1008 public void dispatchSetBackground(Bitmap bmp) {
1009 if (DEBUG) Log.d(TAG, "dispatchSetBackground");
1010 final int count = mCallbacks.size();
1011 for (int i = 0; i < count; i++) {
1012 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1013 if (cb != null) {
1014 cb.onSetBackground(bmp);
1015 }
1016 }
1017 }
1018
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001019 private void handleUserInfoChanged(int userId) {
1020 for (int i = 0; i < mCallbacks.size(); i++) {
1021 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1022 if (cb != null) {
1023 cb.onUserInfoChanged(userId);
1024 }
1025 }
1026 }
1027
Jim Millerdcb3d842012-08-23 19:18:12 -07001028 private KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001029 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -08001030 mSubscriptionManager = SubscriptionManager.from(context);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001031 mAlarmManager = context.getSystemService(AlarmManager.class);
Michael Jurkafff56142012-11-28 16:51:00 -08001032 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001033 mStrongAuthTracker = new StrongAuthTracker(context);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001034
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001035 // Since device can't be un-provisioned, we only need to register a content observer
1036 // to update mDeviceProvisioned when we are...
1037 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001038 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001039 }
Jim Miller47088bb2009-11-24 00:40:16 -08001040
Jim Millerbbf1a742012-07-17 18:30:30 -07001041 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Adrian Roos7b043112015-07-10 13:00:33 -07001042 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001043
Jim Millerbbf1a742012-07-17 18:30:30 -07001044 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001045 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001046 filter.addAction(Intent.ACTION_TIME_TICK);
1047 filter.addAction(Intent.ACTION_TIME_CHANGED);
1048 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
1049 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Jason Monk052082c2015-06-11 11:35:23 -04001050 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001051 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Etan Cohen47051d82015-07-06 16:19:04 -07001052 filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -08001053 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -08001054 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Jim Millerbbf1a742012-07-17 18:30:30 -07001055 context.registerReceiver(mBroadcastReceiver, filter);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001056
Adam Cohenc276e822012-11-08 13:01:08 -08001057 final IntentFilter bootCompleteFilter = new IntentFilter();
1058 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1059 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
1060 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter);
1061
Adrian Roos48c796c2014-09-01 14:59:23 +02001062 final IntentFilter allUserFilter = new IntentFilter();
1063 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
1064 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
1065 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
1066 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
1067 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
1068 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001069 null, null);
1070
Wink Saville071743f2015-01-12 17:11:04 -08001071 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001072 try {
1073 ActivityManagerNative.getDefault().registerUserSwitchObserver(
1074 new IUserSwitchObserver.Stub() {
1075 @Override
1076 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001077 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001078 newUserId, 0, reply));
1079 }
1080 @Override
1081 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001082 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +02001083 newUserId, 0));
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001084 }
Kenny Guy42979622015-04-13 18:03:05 +00001085 @Override
1086 public void onForegroundProfileSwitch(int newProfileId) {
1087 // Ignore.
1088 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001089 }, TAG);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001090 } catch (RemoteException e) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001091 e.rethrowAsRuntimeException();
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001092 }
Adrian Roos46842d92014-03-27 14:58:03 +01001093
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001094 IntentFilter strongAuthTimeoutFilter = new IntentFilter();
1095 strongAuthTimeoutFilter.addAction(ACTION_STRONG_AUTH_TIMEOUT);
1096 context.registerReceiver(mStrongAuthTimeoutReceiver, strongAuthTimeoutFilter,
1097 PERMISSION_SELF, null /* handler */);
Jorim Jaggi237b0612015-05-01 14:28:49 -07001098 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
1099 mTrustManager.registerTrustListener(this);
Adrian Roosb5e47222015-08-14 15:53:06 -07001100 new LockPatternUtils(context).registerStrongAuthTracker(mStrongAuthTracker);
Jim Millerf41fc962014-06-18 16:33:51 -07001101
Jim Miller9f0753f2015-03-23 23:59:22 -07001102 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
Jorim Jaggiea657062015-04-28 13:45:11 -07001103 updateFingerprintListeningState();
Jorim Jaggi3a464782015-08-28 16:59:13 -07001104 if (mFpm != null) {
1105 mFpm.addLockoutResetCallback(mLockoutResetCallback);
1106 }
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001107
1108 mUserManager = context.getSystemService(UserManager.class);
Jorim Jaggiea657062015-04-28 13:45:11 -07001109 }
1110
1111 private void updateFingerprintListeningState() {
1112 boolean shouldListenForFingerprint = shouldListenForFingerprint();
Jorim Jaggi86bed402015-08-20 18:20:02 -07001113 if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING && !shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001114 stopListeningForFingerprint();
Jorim Jaggi86bed402015-08-20 18:20:02 -07001115 } else if (mFingerprintRunningState != FINGERPRINT_STATE_RUNNING
1116 && shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001117 startListeningForFingerprint();
1118 }
1119 }
1120
1121 private boolean shouldListenForFingerprint() {
Jorim Jaggi95e40382015-09-16 15:53:42 -07001122 return (mKeyguardIsVisible || !mDeviceInteractive || mBouncer || mGoingToSleep)
1123 && !mSwitchingUser && !mFingerprintAlreadyAuthenticated
1124 && !isFingerprintDisabled(getCurrentUser());
Jim Miller9f0753f2015-03-23 23:59:22 -07001125 }
1126
Jim Millerce7eb6d2015-04-03 19:29:13 -07001127 private void startListeningForFingerprint() {
Jorim Jaggi86bed402015-08-20 18:20:02 -07001128 if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING) {
1129 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING_RESTARTING);
1130 return;
1131 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001132 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -07001133 int userId = ActivityManager.getCurrentUser();
Jorim Jaggi71448a72015-08-18 19:49:04 -07001134 if (isUnlockWithFingerprintPossible(userId)) {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001135 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001136 mFingerprintCancelSignal.cancel();
1137 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001138 mFingerprintCancelSignal = new CancellationSignal();
Jim Millerf501b582015-06-03 16:36:31 -07001139 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null, userId);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001140 setFingerprintRunningState(FINGERPRINT_STATE_RUNNING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001141 }
1142 }
1143
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001144 public boolean isUnlockWithFingerprintPossible(int userId) {
Selim Cinek3122fa82015-06-18 01:38:59 -07001145 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
1146 && mFpm.getEnrolledFingerprints(userId).size() > 0;
1147 }
1148
Jorim Jaggiea657062015-04-28 13:45:11 -07001149 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001150 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
Jorim Jaggi86bed402015-08-20 18:20:02 -07001151 if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001152 mFingerprintCancelSignal.cancel();
Jim Millerce7eb6d2015-04-03 19:29:13 -07001153 mFingerprintCancelSignal = null;
Jorim Jaggi86bed402015-08-20 18:20:02 -07001154 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001155 }
Jorim Jaggi86bed402015-08-20 18:20:02 -07001156 if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
1157 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
1158 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001159 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001160
Michael Jurkafff56142012-11-28 16:51:00 -08001161 private boolean isDeviceProvisionedInSettingsDb() {
1162 return Settings.Global.getInt(mContext.getContentResolver(),
1163 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1164 }
1165
Jim Millerbbf1a742012-07-17 18:30:30 -07001166 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -08001167 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001168 @Override
1169 public void onChange(boolean selfChange) {
1170 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -08001171 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001172 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001173 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001174 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001175 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001176 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001177 };
1178
1179 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -07001180 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -08001181 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -07001182
1183 // prevent a race condition between where we check the flag and where we register the
1184 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -08001185 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001186 if (provisioned != mDeviceProvisioned) {
1187 mDeviceProvisioned = provisioned;
1188 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001189 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001190 }
1191 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001192 }
1193
Jim Millerbbf1a742012-07-17 18:30:30 -07001194 /**
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001195 * Update the state whether Keyguard currently has a lockscreen wallpaper.
1196 *
1197 * @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper.
1198 */
1199 public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) {
1200 if (hasLockscreenWallpaper != mHasLockscreenWallpaper) {
1201 mHasLockscreenWallpaper = hasLockscreenWallpaper;
1202 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1203 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1204 if (cb != null) {
1205 cb.onHasLockscreenWallpaperChanged(hasLockscreenWallpaper);
1206 }
1207 }
1208 }
1209 }
1210
1211 /**
1212 * @return Whether Keyguard has a lockscreen wallpaper.
1213 */
1214 public boolean hasLockscreenWallpaper() {
1215 return mHasLockscreenWallpaper;
1216 }
1217
1218 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001219 * Handle {@link #MSG_DPM_STATE_CHANGED}
1220 */
Jim Millerb0304762012-03-13 20:01:25 -07001221 protected void handleDevicePolicyManagerStateChanged() {
Adrian Roos733b6632015-08-21 14:32:35 -07001222 updateFingerprintListeningState();
Jim Millerdcb3d842012-08-23 19:18:12 -07001223 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1224 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1225 if (cb != null) {
1226 cb.onDevicePolicyManagerStateChanged();
1227 }
Jim Millerb0304762012-03-13 20:01:25 -07001228 }
1229 }
1230
Jim Millerbbf1a742012-07-17 18:30:30 -07001231 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001232 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -07001233 */
Chris Wrenf41c61b2012-11-29 15:19:54 -05001234 protected void handleUserSwitching(int userId, IRemoteCallback reply) {
Jorim Jaggiaa4d32a2015-05-13 16:30:04 -07001235 mSwitchingUser = true;
1236 updateFingerprintListeningState();
1237
Jim Millerbbf1a742012-07-17 18:30:30 -07001238 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001239 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1240 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001241 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -07001242 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001243 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001244 try {
1245 reply.sendResult(null);
1246 } catch (RemoteException e) {
1247 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001248 }
1249
Jim Millerbbf1a742012-07-17 18:30:30 -07001250 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001251 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
1252 */
1253 protected void handleUserSwitchComplete(int userId) {
Jorim Jaggiaa4d32a2015-05-13 16:30:04 -07001254 mSwitchingUser = false;
1255 updateFingerprintListeningState();
1256
Chris Wrenf41c61b2012-11-29 15:19:54 -05001257 for (int i = 0; i < mCallbacks.size(); i++) {
1258 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1259 if (cb != null) {
1260 cb.onUserSwitchComplete(userId);
1261 }
1262 }
1263 }
1264
1265 /**
Jim Miller90873d52013-09-26 18:11:38 -07001266 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
1267 * keyguard crashes sometime after boot, then it will never receive this
1268 * broadcast and hence not handle the event. This method is ultimately called by
1269 * PhoneWindowManager in this case.
1270 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001271 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001272 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -07001273 }
1274
1275 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001276 * Handle {@link #MSG_BOOT_COMPLETED}
1277 */
1278 protected void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001279 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001280 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001281 for (int i = 0; i < mCallbacks.size(); i++) {
1282 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1283 if (cb != null) {
1284 cb.onBootCompleted();
1285 }
1286 }
1287 }
1288
1289 /**
Jim Miller5ecd8112013-01-09 18:50:26 -08001290 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001291 * destroyed.
1292 */
1293 public boolean hasBootCompleted() {
1294 return mBootCompleted;
1295 }
1296
1297 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001298 * Handle {@link #MSG_DEVICE_PROVISIONED}
1299 */
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001300 protected void handleDeviceProvisioned() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001301 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001302 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1303 if (cb != null) {
1304 cb.onDeviceProvisioned();
1305 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001306 }
Michael Jurkafff56142012-11-28 16:51:00 -08001307 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001308 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -08001309 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
1310 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001311 }
1312 }
1313
Jim Millerbbf1a742012-07-17 18:30:30 -07001314 /**
1315 * Handle {@link #MSG_PHONE_STATE_CHANGED}
1316 */
Jim Millerc23024d2010-02-24 15:37:00 -08001317 protected void handlePhoneStateChanged(String newState) {
1318 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001319 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
1320 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
1321 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
1322 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
1323 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
1324 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
1325 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001326 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001327 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1328 if (cb != null) {
1329 cb.onPhoneStateChanged(mPhoneState);
1330 }
Jim Millerc23024d2010-02-24 15:37:00 -08001331 }
1332 }
1333
Jim Millerbbf1a742012-07-17 18:30:30 -07001334 /**
1335 * Handle {@link #MSG_RINGER_MODE_CHANGED}
1336 */
Jim Miller47088bb2009-11-24 00:40:16 -08001337 protected void handleRingerModeChange(int mode) {
1338 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001339 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -07001340 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001341 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1342 if (cb != null) {
1343 cb.onRingerModeChanged(mode);
1344 }
Jim Miller47088bb2009-11-24 00:40:16 -08001345 }
1346 }
1347
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001348 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001349 * Handle {@link #MSG_TIME_UPDATE}
1350 */
1351 private void handleTimeUpdate() {
1352 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001353 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001354 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1355 if (cb != null) {
1356 cb.onTimeChanged();
1357 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001358 }
1359 }
1360
1361 /**
1362 * Handle {@link #MSG_BATTERY_UPDATE}
1363 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001364 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001365 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001366 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
1367 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07001368 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001369 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001370 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1371 if (cb != null) {
1372 cb.onRefreshBatteryInfo(status);
1373 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001374 }
1375 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001376 }
1377
1378 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001379 * Handle {@link #MSG_SIM_STATE_CHANGE}
1380 */
Jim Miller52a61332014-11-12 19:29:51 -08001381 private void handleSimStateChange(int subId, int slotId, State state) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001382
Jim Miller52a61332014-11-12 19:29:51 -08001383 if (DEBUG_SIM_STATES) {
1384 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
1385 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001386 }
1387
Wink Savillea54bf652014-12-11 13:37:50 -08001388 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08001389 Log.w(TAG, "invalid subId in handleSimStateChange()");
1390 return;
1391 }
1392
1393 SimData data = mSimDatas.get(subId);
1394 final boolean changed;
1395 if (data == null) {
1396 data = new SimData(state, slotId, subId);
1397 mSimDatas.put(subId, data);
1398 changed = true; // no data yet; force update
1399 } else {
1400 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
1401 data.simState = state;
1402 data.subId = subId;
1403 data.slotId = slotId;
1404 }
1405 if (changed && state != State.UNKNOWN) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001406 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001407 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1408 if (cb != null) {
Jim Miller52a61332014-11-12 19:29:51 -08001409 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07001410 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001411 }
1412 }
1413 }
1414
Jim Millerbbf1a742012-07-17 18:30:30 -07001415 /**
Etan Cohen47051d82015-07-06 16:19:04 -07001416 * Handle {@link #MSG_SERVICE_STATE_CHANGE}
1417 */
1418 private void handleServiceStateChange(int subId, ServiceState serviceState) {
1419 if (DEBUG) {
1420 Log.d(TAG,
1421 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
1422 }
1423
1424 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1425 Log.w(TAG, "invalid subId in handleServiceStateChange()");
1426 return;
1427 }
1428
1429 mServiceStates.put(subId, serviceState);
1430
1431 for (int j = 0; j < mCallbacks.size(); j++) {
1432 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
1433 if (cb != null) {
1434 cb.onRefreshCarrierInfo();
1435 }
1436 }
1437 }
1438
1439 /**
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001440 * Notifies that the visibility state of Keyguard has changed.
1441 *
1442 * <p>Needs to be called from the main thread.
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001443 */
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001444 public void onKeyguardVisibilityChanged(boolean showing) {
1445 if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
1446 mKeyguardIsVisible = showing;
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001447 for (int i = 0; i < mCallbacks.size(); i++) {
1448 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1449 if (cb != null) {
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001450 cb.onKeyguardVisibilityChangedRaw(showing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001451 }
1452 }
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001453 if (!showing) {
Jorim Jaggi71448a72015-08-18 19:49:04 -07001454 mFingerprintAlreadyAuthenticated = false;
1455 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001456 updateFingerprintListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001457 }
1458
Brian Colonna7fce3802013-09-17 15:51:32 -04001459 /**
Selim Cinek1fcafc42015-07-20 14:39:25 -07001460 * Handle {@link #MSG_KEYGUARD_RESET}
1461 */
1462 private void handleKeyguardReset() {
1463 if (DEBUG) Log.d(TAG, "handleKeyguardReset");
Adrian Roosf6d51ac2015-09-02 13:26:25 -07001464 updateFingerprintListeningState();
Jorim Jaggi031f7952016-09-01 16:39:26 -07001465 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1466 }
1467
1468 private boolean resolveNeedsSlowUnlockTransition() {
1469 if (mUserManager.isUserUnlocked(getCurrentUser())) {
1470 return false;
1471 }
1472 Intent homeIntent = new Intent(Intent.ACTION_MAIN)
1473 .addCategory(Intent.CATEGORY_HOME);
1474 ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(homeIntent,
1475 0 /* flags */);
1476 return FALLBACK_HOME_COMPONENT.equals(resolveInfo.getComponentInfo().getComponentName());
Selim Cinek1fcafc42015-07-20 14:39:25 -07001477 }
1478
1479 /**
Adrian Roosb6011622014-05-14 15:52:53 +02001480 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
1481 * @see #sendKeyguardBouncerChanged(boolean)
1482 */
1483 private void handleKeyguardBouncerChanged(int bouncer) {
1484 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
1485 boolean isBouncer = (bouncer == 1);
1486 mBouncer = isBouncer;
1487 for (int i = 0; i < mCallbacks.size(); i++) {
1488 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1489 if (cb != null) {
1490 cb.onKeyguardBouncerChanged(isBouncer);
1491 }
1492 }
Jorim Jaggi3cf7eef2015-09-10 14:36:19 -07001493 updateFingerprintListeningState();
Adrian Roosb6011622014-05-14 15:52:53 +02001494 }
1495
1496 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04001497 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
1498 */
1499 private void handleReportEmergencyCallAction() {
1500 for (int i = 0; i < mCallbacks.size(); i++) {
1501 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1502 if (cb != null) {
1503 cb.onEmergencyCallAction();
1504 }
1505 }
1506 }
1507
Jim Miller16464b82011-10-20 21:10:13 -07001508 private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001509 final boolean nowPluggedIn = current.isPluggedIn();
1510 final boolean wasPluggedIn = old.isPluggedIn();
Jim Miller79a444a2011-02-15 15:02:11 -08001511 final boolean stateChangedWhilePluggedIn =
Jim Miller16464b82011-10-20 21:10:13 -07001512 wasPluggedIn == true && nowPluggedIn == true
1513 && (old.status != current.status);
1514
1515 // change in plug state is always interesting
1516 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001517 return true;
1518 }
1519
1520 // change in battery level while plugged in
Jim Miller16464b82011-10-20 21:10:13 -07001521 if (nowPluggedIn && old.level != current.level) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001522 return true;
1523 }
1524
Jim Miller16464b82011-10-20 21:10:13 -07001525 // change where battery needs charging
Jim Millerbbf1a742012-07-17 18:30:30 -07001526 if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
Jim Miller16464b82011-10-20 21:10:13 -07001527 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001528 }
Adrian Roos76dc5a52015-07-21 16:20:36 -07001529
1530 // change in charging current while plugged in
Adrian Roos0c859ae2015-11-23 16:47:50 -08001531 if (nowPluggedIn && current.maxChargingWattage != old.maxChargingWattage) {
Adrian Roos76dc5a52015-07-21 16:20:36 -07001532 return true;
1533 }
1534
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001535 return false;
1536 }
1537
1538 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001539 * Remove the given observer's callback.
1540 *
Jim Miller6212cc02012-09-05 17:35:31 -07001541 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001542 */
Jim Miller6212cc02012-09-05 17:35:31 -07001543 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
1544 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
1545 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1546 if (mCallbacks.get(i).get() == callback) {
1547 mCallbacks.remove(i);
1548 }
1549 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001550 }
1551
1552 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001553 * Register to receive notifications about general keyguard information
1554 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07001555 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001556 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001557 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Jim Miller6212cc02012-09-05 17:35:31 -07001558 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
1559 // Prevent adding duplicate callbacks
1560 for (int i = 0; i < mCallbacks.size(); i++) {
1561 if (mCallbacks.get(i).get() == callback) {
1562 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
1563 new Exception("Called by"));
1564 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07001565 }
1566 }
Jim Miller6212cc02012-09-05 17:35:31 -07001567 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
1568 removeCallback(null); // remove unused references
1569 sendUpdates(callback);
1570 }
1571
1572 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
1573 // Notify listener of the current state
1574 callback.onRefreshBatteryInfo(mBatteryStatus);
1575 callback.onTimeChanged();
1576 callback.onRingerModeChanged(mRingMode);
1577 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05001578 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07001579 callback.onClockVisibilityChanged();
Jim Miller52a61332014-11-12 19:29:51 -08001580 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
1581 final SimData state = data.getValue();
1582 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
1583 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001584 }
1585
Selim Cinek1fcafc42015-07-20 14:39:25 -07001586 public void sendKeyguardReset() {
1587 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
1588 }
1589
Adrian Roosb6011622014-05-14 15:52:53 +02001590 /**
1591 * @see #handleKeyguardBouncerChanged(int)
1592 */
1593 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
1594 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
1595 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
1596 message.arg1 = showingBouncer ? 1 : 0;
1597 message.sendToTarget();
1598 }
1599
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001600 /**
Jim Miller90d5d462011-11-17 16:57:01 -08001601 * 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 -08001602 * have the information earlier than waiting for the intent
1603 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08001604 *
1605 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
1606 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001607 */
Jim Miller52a61332014-11-12 19:29:51 -08001608 public void reportSimUnlocked(int subId) {
1609 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
1610 int slotId = SubscriptionManager.getSlotId(subId);
1611 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001612 }
1613
Brian Colonna7fce3802013-09-17 15:51:32 -04001614 /**
1615 * Report that the emergency call button has been pressed and the emergency dialer is
1616 * about to be displayed.
1617 *
1618 * @param bypassHandler runs immediately.
1619 *
1620 * NOTE: Must be called from UI thread if bypassHandler == true.
1621 */
1622 public void reportEmergencyCallAction(boolean bypassHandler) {
1623 if (!bypassHandler) {
1624 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
1625 } else {
1626 handleReportEmergencyCallAction();
1627 }
1628 }
1629
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001630 /**
1631 * @return Whether the device is provisioned (whether they have gone through
1632 * the setup wizard)
1633 */
1634 public boolean isDeviceProvisioned() {
1635 return mDeviceProvisioned;
1636 }
1637
Jorim Jaggi9f743032015-05-04 15:22:40 -07001638 public void clearFailedUnlockAttempts() {
1639 mFailedAttempts.delete(sCurrentUser);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001640 }
1641
Xiyuan Xiace64cea2016-01-06 08:51:16 -08001642 public int getFailedUnlockAttempts(int userId) {
1643 return mFailedAttempts.get(userId, 0);
Jorim Jaggi9f743032015-05-04 15:22:40 -07001644 }
1645
Xiyuan Xiace64cea2016-01-06 08:51:16 -08001646 public void reportFailedStrongAuthUnlockAttempt(int userId) {
1647 mFailedAttempts.put(userId, getFailedUnlockAttempts(userId) + 1);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001648 }
1649
Jim Millerf41fc962014-06-18 16:33:51 -07001650 public void clearFingerprintRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07001651 mUserFingerprintAuthenticated.clear();
Jim Millerf41fc962014-06-18 16:33:51 -07001652 }
1653
Jim Miller52a61332014-11-12 19:29:51 -08001654 public boolean isSimPinVoiceSecure() {
1655 // TODO: only count SIMs that handle voice
1656 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07001657 }
1658
1659 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08001660 // True if any SIM is pin secure
1661 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
1662 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
1663 }
1664 return false;
1665 }
1666
Jason Monk9ff69bd2014-12-02 16:43:17 -05001667 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08001668 if (mSimDatas.containsKey(subId)) {
1669 return mSimDatas.get(subId).simState;
1670 } else {
1671 return State.UNKNOWN;
1672 }
1673 }
1674
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001675 /**
1676 * @return true if and only if the state has changed for the specified {@code slotId}
1677 */
1678 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08001679
1680 // This is awful. It exists because there are two APIs for getting the SIM status
1681 // that don't return the complete set of values and have different types. In Keyguard we
1682 // need IccCardConstants, but TelephonyManager would only give us
1683 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08001684 final TelephonyManager tele = TelephonyManager.from(mContext);
1685 int simState = tele.getSimState(slotId);
Jim Miller52a61332014-11-12 19:29:51 -08001686 State state;
1687 try {
xinhe18b9c3c2014-12-02 15:03:20 -08001688 state = State.intToState(simState);
Jim Miller52a61332014-11-12 19:29:51 -08001689 } catch(IllegalArgumentException ex) {
xinhe18b9c3c2014-12-02 15:03:20 -08001690 Log.w(TAG, "Unknown sim state: " + simState);
Jim Miller52a61332014-11-12 19:29:51 -08001691 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05001692 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001693 SimData data = mSimDatas.get(subId);
1694 final boolean changed;
1695 if (data == null) {
1696 data = new SimData(state, slotId, subId);
1697 mSimDatas.put(subId, data);
1698 changed = true; // no data yet; force update
1699 } else {
1700 changed = data.simState != state;
1701 data.simState = state;
1702 }
1703 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07001704 }
1705
1706 public static boolean isSimPinSecure(IccCardConstants.State state) {
1707 final IccCardConstants.State simState = state;
1708 return (simState == IccCardConstants.State.PIN_REQUIRED
1709 || simState == IccCardConstants.State.PUK_REQUIRED
1710 || simState == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07001711 }
Jim Miller8f09fd22013-03-14 19:04:28 -07001712
1713 public DisplayClientState getCachedDisplayClientState() {
1714 return mDisplayClientState;
1715 }
Jim Miller20daffd2013-10-07 14:59:53 -07001716
1717 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
1718 // (KeyguardViewMediator, KeyguardHostView)
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001719 public void dispatchStartedWakingUp() {
1720 synchronized (this) {
1721 mDeviceInteractive = true;
1722 }
1723 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
1724 }
1725
Jorim Jaggi95e40382015-09-16 15:53:42 -07001726 public void dispatchStartedGoingToSleep(int why) {
1727 mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
1728 }
1729
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001730 public void dispatchFinishedGoingToSleep(int why) {
1731 synchronized(this) {
1732 mDeviceInteractive = false;
1733 }
1734 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
1735 }
1736
Jim Miller20daffd2013-10-07 14:59:53 -07001737 public void dispatchScreenTurnedOn() {
1738 synchronized (this) {
1739 mScreenOn = true;
1740 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001741 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
Jim Miller20daffd2013-10-07 14:59:53 -07001742 }
1743
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001744 public void dispatchScreenTurnedOff() {
Jim Miller20daffd2013-10-07 14:59:53 -07001745 synchronized(this) {
1746 mScreenOn = false;
1747 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001748 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
Jim Miller20daffd2013-10-07 14:59:53 -07001749 }
1750
Selim Cinek99415392016-09-09 14:58:41 -07001751 public void dispatchDreamingStarted() {
1752 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 1, 0));
1753 }
1754
1755 public void dispatchDreamingStopped() {
1756 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 0, 0));
1757 }
1758
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001759 public boolean isDeviceInteractive() {
1760 return mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -07001761 }
Jim Miller52a61332014-11-12 19:29:51 -08001762
Jorim Jaggi95e40382015-09-16 15:53:42 -07001763 public boolean isGoingToSleep() {
1764 return mGoingToSleep;
1765 }
1766
Jim Miller52a61332014-11-12 19:29:51 -08001767 /**
1768 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
1769 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08001770 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08001771 */
1772 public int getNextSubIdForState(State state) {
1773 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08001774 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08001775 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
1776 for (int i = 0; i < list.size(); i++) {
1777 final SubscriptionInfo info = list.get(i);
1778 final int id = info.getSubscriptionId();
1779 int slotId = SubscriptionManager.getSlotId(id);
1780 if (state == getSimState(id) && bestSlotId > slotId ) {
1781 resultId = id;
1782 bestSlotId = slotId;
1783 }
1784 }
1785 return resultId;
1786 }
1787
1788 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
1789 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
1790 for (int i = 0; i < list.size(); i++) {
1791 SubscriptionInfo info = list.get(i);
1792 if (subId == info.getSubscriptionId()) return info;
1793 }
1794 return null; // not found
1795 }
Jason Monkab525272015-07-13 17:02:49 -04001796
1797 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1798 pw.println("KeyguardUpdateMonitor state:");
1799 pw.println(" SIM States:");
1800 for (SimData data : mSimDatas.values()) {
1801 pw.println(" " + data.toString());
1802 }
1803 pw.println(" Subs:");
1804 if (mSubscriptionInfo != null) {
1805 for (int i = 0; i < mSubscriptionInfo.size(); i++) {
1806 pw.println(" " + mSubscriptionInfo.get(i));
1807 }
1808 }
1809 pw.println(" Service states:");
1810 for (int subId : mServiceStates.keySet()) {
1811 pw.println(" " + subId + "=" + mServiceStates.get(subId));
1812 }
Jim Millerd72d5ac2015-09-29 18:55:32 -07001813 if (mFpm != null && mFpm.isHardwareDetected()) {
1814 final int userId = ActivityManager.getCurrentUser();
1815 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
1816 pw.println(" Fingerprint state (user=" + userId + ")");
1817 pw.println(" allowed=" + isUnlockingWithFingerprintAllowed());
1818 pw.println(" auth'd=" + mUserFingerprintAuthenticated.get(userId));
1819 pw.println(" authSinceBoot="
1820 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
1821 pw.println(" disabled(DPM)=" + isFingerprintDisabled(userId));
1822 pw.println(" possible=" + isUnlockWithFingerprintPossible(userId));
1823 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
1824 pw.println(" timedout=" + hasFingerprintUnlockTimedOut(userId));
1825 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
1826 }
Jason Monkab525272015-07-13 17:02:49 -04001827 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001828}