blob: 6a2949a5ed9f81c70126d969187332291f0dc65e [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 Jaggidadafd42016-09-30 07:20:25 -070019import static android.content.Intent.ACTION_USER_UNLOCKED;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -070020import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
21import static android.os.BatteryManager.BATTERY_STATUS_FULL;
22import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
23import static android.os.BatteryManager.EXTRA_HEALTH;
24import static android.os.BatteryManager.EXTRA_LEVEL;
25import static android.os.BatteryManager.EXTRA_MAX_CHARGING_CURRENT;
26import static android.os.BatteryManager.EXTRA_MAX_CHARGING_VOLTAGE;
27import static android.os.BatteryManager.EXTRA_PLUGGED;
28import static android.os.BatteryManager.EXTRA_STATUS;
29
Jorim Jaggiccdfa932015-04-13 16:29:48 -070030import android.app.ActivityManager;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020031import android.app.AlarmManager;
Jim Miller8f09fd22013-03-14 19:04:28 -070032import android.app.PendingIntent;
Sudheer Shanka2c4522c2016-08-27 20:53:28 -070033import android.app.UserSwitchObserver;
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;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700139 private static final int MSG_USER_UNLOCKED = 334;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800140
Jorim Jaggi86bed402015-08-20 18:20:02 -0700141 /** Fingerprint state: Not listening to fingerprint. */
142 private static final int FINGERPRINT_STATE_STOPPED = 0;
143
144 /** Fingerprint state: Listening. */
145 private static final int FINGERPRINT_STATE_RUNNING = 1;
146
147 /**
148 * Fingerprint state: Cancelling and waiting for the confirmation from FingerprintService to
149 * send us the confirmation that cancellation has happened.
150 */
151 private static final int FINGERPRINT_STATE_CANCELLING = 2;
152
153 /**
154 * Fingerprint state: During cancelling we got another request to start listening, so when we
155 * receive the cancellation done signal, we should start listening again.
156 */
157 private static final int FINGERPRINT_STATE_CANCELLING_RESTARTING = 3;
158
Adrian Roos0c859ae2015-11-23 16:47:50 -0800159 private static final int DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT = 5000000;
160
Jorim Jaggi031f7952016-09-01 16:39:26 -0700161 private static final ComponentName FALLBACK_HOME_COMPONENT = new ComponentName(
162 "com.android.settings", "com.android.settings.FallbackHome");
163
Jim Millerdcb3d842012-08-23 19:18:12 -0700164 private static KeyguardUpdateMonitor sInstance;
165
Jim Millerbbf1a742012-07-17 18:30:30 -0700166 private final Context mContext;
Jim Miller52a61332014-11-12 19:29:51 -0800167 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
Etan Cohen47051d82015-07-06 16:19:04 -0700168 HashMap<Integer, ServiceState> mServiceStates = new HashMap<Integer, ServiceState>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700169
Jim Millerbbf1a742012-07-17 18:30:30 -0700170 private int mRingMode;
171 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400172 private boolean mKeyguardIsVisible;
Jorim Jaggi71448a72015-08-18 19:49:04 -0700173
174 /**
175 * If true, fingerprint was already authenticated and we don't need to start listening again
176 * until the Keyguard has been dismissed.
177 */
178 private boolean mFingerprintAlreadyAuthenticated;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700179 private boolean mGoingToSleep;
Adrian Roosb6011622014-05-14 15:52:53 +0200180 private boolean mBouncer;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800181 private boolean mBootCompleted;
Jorim Jaggi031f7952016-09-01 16:39:26 -0700182 private boolean mNeedsSlowUnlockTransition;
Jorim Jaggid11d1a92016-08-16 16:02:32 -0700183 private boolean mHasLockscreenWallpaper;
Jim Millerbbf1a742012-07-17 18:30:30 -0700184
Jim Millerdcb3d842012-08-23 19:18:12 -0700185 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700186 private boolean mDeviceProvisioned;
187
Jim Millerdcb3d842012-08-23 19:18:12 -0700188 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700189 private BatteryStatus mBatteryStatus;
190
Jim Millerdcb3d842012-08-23 19:18:12 -0700191 // Password attempts
Jorim Jaggi9f743032015-05-04 15:22:40 -0700192 private SparseIntArray mFailedAttempts = new SparseIntArray();
Brian Colonnacc4104f2012-10-09 17:50:46 -0400193
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700194 /** Tracks whether strong authentication hasn't been used since quite some time per user. */
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700195 private ArraySet<Integer> mStrongAuthNotTimedOut = new ArraySet<>();
Rakesh Iyera7aa4d62016-01-19 17:27:23 -0800196 private final StrongAuthTracker mStrongAuthTracker;
Jim Millerbbf1a742012-07-17 18:30:30 -0700197
Jim Miller6212cc02012-09-05 17:35:31 -0700198 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700199 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800200 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700201
Brian Colonnaa5239892013-04-15 11:45:40 -0400202 private boolean mSwitchingUser;
203
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700204 private boolean mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -0700205 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800206 private SubscriptionManager mSubscriptionManager;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700207 private AlarmManager mAlarmManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800208 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700209 private TrustManager mTrustManager;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700210 private UserManager mUserManager;
Jorim Jaggi86bed402015-08-20 18:20:02 -0700211 private int mFingerprintRunningState = FINGERPRINT_STATE_STOPPED;
Jim Miller20daffd2013-10-07 14:59:53 -0700212
Jim Millerbbf1a742012-07-17 18:30:30 -0700213 private final Handler mHandler = new Handler() {
214 @Override
215 public void handleMessage(Message msg) {
216 switch (msg.what) {
217 case MSG_TIME_UPDATE:
218 handleTimeUpdate();
219 break;
220 case MSG_BATTERY_UPDATE:
221 handleBatteryUpdate((BatteryStatus) msg.obj);
222 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700223 case MSG_SIM_STATE_CHANGE:
Jim Miller52a61332014-11-12 19:29:51 -0800224 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700225 break;
226 case MSG_RINGER_MODE_CHANGED:
227 handleRingerModeChange(msg.arg1);
228 break;
229 case MSG_PHONE_STATE_CHANGED:
Adrian Roosb6011622014-05-14 15:52:53 +0200230 handlePhoneStateChanged((String) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700231 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700232 case MSG_DEVICE_PROVISIONED:
233 handleDeviceProvisioned();
234 break;
235 case MSG_DPM_STATE_CHANGED:
236 handleDevicePolicyManagerStateChanged();
237 break;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500238 case MSG_USER_SWITCHING:
Adrian Roosb6011622014-05-14 15:52:53 +0200239 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
Chris Wrenf41c61b2012-11-29 15:19:54 -0500240 break;
241 case MSG_USER_SWITCH_COMPLETE:
242 handleUserSwitchComplete(msg.arg1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700243 break;
Selim Cinek1fcafc42015-07-20 14:39:25 -0700244 case MSG_KEYGUARD_RESET:
245 handleKeyguardReset();
246 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200247 case MSG_KEYGUARD_BOUNCER_CHANGED:
248 handleKeyguardBouncerChanged(msg.arg1);
249 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800250 case MSG_BOOT_COMPLETED:
251 handleBootCompleted();
252 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700253 case MSG_USER_INFO_CHANGED:
254 handleUserInfoChanged(msg.arg1);
255 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400256 case MSG_REPORT_EMERGENCY_CALL_ACTION:
257 handleReportEmergencyCallAction();
258 break;
Jorim Jaggi95e40382015-09-16 15:53:42 -0700259 case MSG_STARTED_GOING_TO_SLEEP:
260 handleStartedGoingToSleep(msg.arg1);
261 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700262 case MSG_FINISHED_GOING_TO_SLEEP:
263 handleFinishedGoingToSleep(msg.arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700264 break;
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700265 case MSG_STARTED_WAKING_UP:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700266 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_STARTED_WAKING_UP");
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700267 handleStartedWakingUp();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700268 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -0700269 break;
Jorim Jaggie7b12522014-08-06 16:41:21 +0200270 case MSG_FACE_UNLOCK_STATE_CHANGED:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700271 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_FACE_UNLOCK_STATE_CHANGED");
Adrian Roos4a410172014-08-20 17:41:44 +0200272 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
Nick Desaulniers1d396752016-07-25 15:05:33 -0700273 Trace.endSection();
Jorim Jaggie7b12522014-08-06 16:41:21 +0200274 break;
Jim Miller52a61332014-11-12 19:29:51 -0800275 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
276 handleSimSubscriptionInfoChanged();
277 break;
Jason Monk052082c2015-06-11 11:35:23 -0400278 case MSG_AIRPLANE_MODE_CHANGED:
279 handleAirplaneModeChanged();
280 break;
Etan Cohen47051d82015-07-06 16:19:04 -0700281 case MSG_SERVICE_STATE_CHANGE:
282 handleServiceStateChange(msg.arg1, (ServiceState) msg.obj);
283 break;
Jorim Jaggif1518da2015-07-30 11:56:36 -0700284 case MSG_SCREEN_TURNED_ON:
285 handleScreenTurnedOn();
286 break;
287 case MSG_SCREEN_TURNED_OFF:
Nick Desaulniers1d396752016-07-25 15:05:33 -0700288 Trace.beginSection("KeyguardUpdateMonitor#handler MSG_SCREEN_TURNED_ON");
Jorim Jaggif1518da2015-07-30 11:56:36 -0700289 handleScreenTurnedOff();
Nick Desaulniers1d396752016-07-25 15:05:33 -0700290 Trace.endSection();
Jorim Jaggif1518da2015-07-30 11:56:36 -0700291 break;
Selim Cinek99415392016-09-09 14:58:41 -0700292 case MSG_DREAMING_STATE_CHANGED:
293 handleDreamingStateChanged(msg.arg1);
294 break;
Jorim Jaggidadafd42016-09-30 07:20:25 -0700295 case MSG_USER_UNLOCKED:
296 handleUserUnlocked();
297 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700298 }
299 }
300 };
301
Wink Savilled09c4ca2014-11-22 10:08:16 -0800302 private OnSubscriptionsChangedListener mSubscriptionListener =
303 new OnSubscriptionsChangedListener() {
Jim Miller52a61332014-11-12 19:29:51 -0800304 @Override
Wink Savilled09c4ca2014-11-22 10:08:16 -0800305 public void onSubscriptionsChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800306 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
307 }
308 };
309
Adrian Roos46842d92014-03-27 14:58:03 +0100310 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200311 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Jim Miller9f0753f2015-03-23 23:59:22 -0700312 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200313 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100314
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700315 private static int sCurrentUser;
316
317 public synchronized static void setCurrentUser(int currentUser) {
318 sCurrentUser = currentUser;
319 }
320
321 public synchronized static int getCurrentUser() {
322 return sCurrentUser;
323 }
324
Adrian Roos46842d92014-03-27 14:58:03 +0100325 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700326 public void onTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos46842d92014-03-27 14:58:03 +0100327 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200328 for (int i = 0; i < mCallbacks.size(); i++) {
329 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
330 if (cb != null) {
331 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700332 if (enabled && flags != 0) {
333 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200334 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200335 }
336 }
Adrian Roos46842d92014-03-27 14:58:03 +0100337 }
338
Jim Miller52a61332014-11-12 19:29:51 -0800339 protected void handleSimSubscriptionInfoChanged() {
340 if (DEBUG_SIM_STATES) {
341 Log.v(TAG, "onSubscriptionInfoChanged()");
Wink Savilled09c4ca2014-11-22 10:08:16 -0800342 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
343 if (sil != null) {
344 for (SubscriptionInfo subInfo : sil) {
345 Log.v(TAG, "SubInfo:" + subInfo);
346 }
347 } else {
348 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800349 }
350 }
351 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
352
353 // Hack level over 9000: Because the subscription id is not yet valid when we see the
354 // first update in handleSimStateChange, we need to force refresh all all SIM states
355 // so the subscription id for them is consistent.
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100356 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
Jim Miller52a61332014-11-12 19:29:51 -0800357 for (int i = 0; i < subscriptionInfos.size(); i++) {
358 SubscriptionInfo info = subscriptionInfos.get(i);
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100359 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
360 if (changed) {
361 changedSubscriptions.add(info);
362 }
Jim Miller52a61332014-11-12 19:29:51 -0800363 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100364 for (int i = 0; i < changedSubscriptions.size(); i++) {
365 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800366 for (int j = 0; j < mCallbacks.size(); j++) {
367 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
368 if (cb != null) {
369 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
370 }
371 }
372 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500373 for (int j = 0; j < mCallbacks.size(); j++) {
374 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
375 if (cb != null) {
376 cb.onRefreshCarrierInfo();
377 }
378 }
Jim Miller52a61332014-11-12 19:29:51 -0800379 }
380
Jason Monk052082c2015-06-11 11:35:23 -0400381 private void handleAirplaneModeChanged() {
382 for (int j = 0; j < mCallbacks.size(); j++) {
383 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
384 if (cb != null) {
385 cb.onRefreshCarrierInfo();
386 }
387 }
388 }
389
Wink Savilled09c4ca2014-11-22 10:08:16 -0800390 /** @return List of SubscriptionInfo records, maybe empty but never null */
Adrian Roos316bf542016-08-23 17:53:07 +0200391 public List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800392 List<SubscriptionInfo> sil = mSubscriptionInfo;
393 if (sil == null || forceReload) {
394 sil = mSubscriptionManager.getActiveSubscriptionInfoList();
395 }
396 if (sil == null) {
397 // getActiveSubscriptionInfoList was null callers expect an empty list.
398 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
399 } else {
400 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800401 }
402 return mSubscriptionInfo;
403 }
404
Adrian Roos7861c662014-07-25 15:37:28 +0200405 @Override
406 public void onTrustManagedChanged(boolean managed, int userId) {
407 mUserTrustIsManaged.put(userId, managed);
408
409 for (int i = 0; i < mCallbacks.size(); i++) {
410 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
411 if (cb != null) {
412 cb.onTrustManagedChanged(userId);
413 }
414 }
415 }
416
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700417 private void onFingerprintAuthenticated(int userId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700418 Trace.beginSection("KeyGuardUpdateMonitor#onFingerPrintAuthenticated");
Jim Miller9f0753f2015-03-23 23:59:22 -0700419 mUserFingerprintAuthenticated.put(userId, true);
Jorim Jaggi71448a72015-08-18 19:49:04 -0700420
421 // If fingerprint unlocking is allowed, this event will lead to a Keyguard dismiss or to a
422 // wake-up (if Keyguard is not showing), so we don't need to listen until Keyguard is
423 // fully gone.
424 mFingerprintAlreadyAuthenticated = isUnlockingWithFingerprintAllowed();
Jim Millerf41fc962014-06-18 16:33:51 -0700425 for (int i = 0; i < mCallbacks.size(); i++) {
426 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
427 if (cb != null) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700428 cb.onFingerprintAuthenticated(userId);
Jim Millerf41fc962014-06-18 16:33:51 -0700429 }
430 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700431 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700432 }
433
Jim Millerce7eb6d2015-04-03 19:29:13 -0700434 private void handleFingerprintAuthFailed() {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700435 for (int i = 0; i < mCallbacks.size(); i++) {
436 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
437 if (cb != null) {
438 cb.onFingerprintAuthFailed();
439 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700440 }
Jim Millerce7eb6d2015-04-03 19:29:13 -0700441 handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized));
442 }
Jim Millerf41fc962014-06-18 16:33:51 -0700443
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700444 private void handleFingerprintAcquired(int acquireInfo) {
445 if (acquireInfo != FingerprintManager.FINGERPRINT_ACQUIRED_GOOD) {
446 return;
447 }
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700448 for (int i = 0; i < mCallbacks.size(); i++) {
449 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
450 if (cb != null) {
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700451 cb.onFingerprintAcquired();
Jorim Jaggi007f0e82015-08-14 13:56:01 -0700452 }
453 }
454 }
455
Jim Miller837fa7e2016-08-08 20:16:22 -0700456 private void handleFingerprintAuthenticated(int authUserId) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700457 Trace.beginSection("KeyGuardUpdateMonitor#handlerFingerPrintAuthenticated");
Jim Millerf41fc962014-06-18 16:33:51 -0700458 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700459 final int userId;
460 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -0800461 userId = ActivityManager.getService().getCurrentUser().id;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700462 } catch (RemoteException e) {
463 Log.e(TAG, "Failed to get current user id: ", e);
464 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700465 }
Jim Miller837fa7e2016-08-08 20:16:22 -0700466 if (userId != authUserId) {
467 Log.d(TAG, "Fingerprint authenticated for wrong user: " + authUserId);
468 return;
469 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700470 if (isFingerprintDisabled(userId)) {
471 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
472 return;
473 }
Jorim Jaggi83eb6bb2015-08-17 17:38:58 -0700474 onFingerprintAuthenticated(userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700475 } finally {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700476 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
Jim Millerf41fc962014-06-18 16:33:51 -0700477 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700478 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700479 }
480
Jim Miller9f0753f2015-03-23 23:59:22 -0700481 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700482 for (int i = 0; i < mCallbacks.size(); i++) {
483 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
484 if (cb != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700485 cb.onFingerprintHelp(msgId, helpString);
486 }
487 }
488 }
489
490 private void handleFingerprintError(int msgId, String errString) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700491 if (msgId == FingerprintManager.FINGERPRINT_ERROR_CANCELED
492 && mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
493 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
494 startListeningForFingerprint();
495 } else {
496 setFingerprintRunningState(FINGERPRINT_STATE_STOPPED);
497 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700498 for (int i = 0; i < mCallbacks.size(); i++) {
499 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
500 if (cb != null) {
501 cb.onFingerprintError(msgId, errString);
Jim Millerf41fc962014-06-18 16:33:51 -0700502 }
503 }
504 }
505
Jorim Jaggi3a464782015-08-28 16:59:13 -0700506 private void handleFingerprintLockoutReset() {
507 updateFingerprintListeningState();
508 }
509
Jorim Jaggi86bed402015-08-20 18:20:02 -0700510 private void setFingerprintRunningState(int fingerprintRunningState) {
511 boolean wasRunning = mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
512 boolean isRunning = fingerprintRunningState == FINGERPRINT_STATE_RUNNING;
513 mFingerprintRunningState = fingerprintRunningState;
514
515 // Clients of KeyguardUpdateMonitor don't care about the internal state about the
516 // asynchronousness of the cancel cycle. So only notify them if the actualy running state
517 // has changed.
518 if (wasRunning != isRunning) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700519 notifyFingerprintRunningStateChanged();
520 }
521 }
522
523 private void notifyFingerprintRunningStateChanged() {
524 for (int i = 0; i < mCallbacks.size(); i++) {
525 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
526 if (cb != null) {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700527 cb.onFingerprintRunningStateChanged(isFingerprintDetectionRunning());
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700528 }
529 }
530 }
Adrian Roos4a410172014-08-20 17:41:44 +0200531 private void handleFaceUnlockStateChanged(boolean running, int userId) {
532 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200533 for (int i = 0; i < mCallbacks.size(); i++) {
534 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
535 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200536 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200537 }
538 }
539 }
540
Adrian Roos4a410172014-08-20 17:41:44 +0200541 public boolean isFaceUnlockRunning(int userId) {
542 return mUserFaceUnlockRunning.get(userId);
543 }
544
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700545 public boolean isFingerprintDetectionRunning() {
Jorim Jaggi86bed402015-08-20 18:20:02 -0700546 return mFingerprintRunningState == FINGERPRINT_STATE_RUNNING;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700547 }
548
Jim Miller50e62182014-04-23 17:25:00 -0700549 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100550 // Don't allow trust agent if device is secured with a SIM PIN. This is here
551 // mainly because there's no other way to prompt the user to enter their SIM PIN
552 // once they get past the keyguard screen.
553 final boolean disabledBySimPin = isSimPinSecure();
554 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700555 }
556
Jim Miller06e34502014-07-17 14:46:05 -0700557 private boolean isFingerprintDisabled(int userId) {
558 final DevicePolicyManager dpm =
559 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
560 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
Adrian Roos733b6632015-08-21 14:32:35 -0700561 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0
562 || isSimPinSecure();
Jim Miller06e34502014-07-17 14:46:05 -0700563 }
564
Selim Cineke8bae622015-07-15 13:24:06 -0700565 public boolean getUserCanSkipBouncer(int userId) {
Selim Cinek1fcafc42015-07-20 14:39:25 -0700566 return getUserHasTrust(userId) || (mUserFingerprintAuthenticated.get(userId)
567 && isUnlockingWithFingerprintAllowed());
Selim Cineke8bae622015-07-15 13:24:06 -0700568 }
569
Adrian Roos46842d92014-03-27 14:58:03 +0100570 public boolean getUserHasTrust(int userId) {
Selim Cineke8bae622015-07-15 13:24:06 -0700571 return !isTrustDisabled(userId) && mUserHasTrust.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100572 }
573
Adrian Roos7861c662014-07-25 15:37:28 +0200574 public boolean getUserTrustIsManaged(int userId) {
575 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
576 }
577
Selim Cinek1fcafc42015-07-20 14:39:25 -0700578 public boolean isUnlockingWithFingerprintAllowed() {
Adrian Roosb5e47222015-08-14 15:53:06 -0700579 return mStrongAuthTracker.isUnlockingWithFingerprintAllowed()
580 && !hasFingerprintUnlockTimedOut(sCurrentUser);
581 }
582
Jorim Jaggi031f7952016-09-01 16:39:26 -0700583 public boolean needsSlowUnlockTransition() {
584 return mNeedsSlowUnlockTransition;
Jorim Jaggie8fde5d2016-06-30 23:41:37 -0700585 }
586
Adrian Roosb5e47222015-08-14 15:53:06 -0700587 public StrongAuthTracker getStrongAuthTracker() {
588 return mStrongAuthTracker;
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700589 }
590
591 /**
592 * @return true if the user hasn't use strong authentication (pattern, PIN, password) since a
593 * while and thus can't unlock with fingerprint, false otherwise
594 */
595 public boolean hasFingerprintUnlockTimedOut(int userId) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700596 return !mStrongAuthNotTimedOut.contains(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700597 }
598
599 public void reportSuccessfulStrongAuthUnlockAttempt() {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700600 mStrongAuthNotTimedOut.add(sCurrentUser);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700601 scheduleStrongAuthTimeout();
Jim Millere0507bb2015-08-12 20:30:34 -0700602 if (mFpm != null) {
603 byte[] token = null; /* TODO: pass real auth token once fp HAL supports it */
604 mFpm.resetTimeout(token);
605 }
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700606 }
607
608 private void scheduleStrongAuthTimeout() {
Michal Karpinski8f010dd2016-06-21 15:05:53 +0100609 final DevicePolicyManager dpm =
610 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
611 long when = SystemClock.elapsedRealtime() + dpm.getRequiredStrongAuthTimeout(null,
612 sCurrentUser);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700613 Intent intent = new Intent(ACTION_STRONG_AUTH_TIMEOUT);
614 intent.putExtra(USER_ID, sCurrentUser);
615 PendingIntent sender = PendingIntent.getBroadcast(mContext,
616 sCurrentUser, intent, PendingIntent.FLAG_CANCEL_CURRENT);
617 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, when, sender);
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700618 notifyStrongAuthStateChanged(sCurrentUser);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700619 }
620
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700621 private void notifyStrongAuthStateChanged(int userId) {
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700622 for (int i = 0; i < mCallbacks.size(); i++) {
623 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
624 if (cb != null) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700625 cb.onStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700626 }
627 }
Selim Cinek1fcafc42015-07-20 14:39:25 -0700628 }
629
Jim Miller8f09fd22013-03-14 19:04:28 -0700630 static class DisplayClientState {
631 public int clientGeneration;
632 public boolean clearing;
633 public PendingIntent intent;
634 public int playbackState;
635 public long playbackEventTime;
636 }
637
638 private DisplayClientState mDisplayClientState = new DisplayClientState();
639
Jim Millerbbf1a742012-07-17 18:30:30 -0700640 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
641
Jim Millerd72d5ac2015-09-29 18:55:32 -0700642 @Override
Jim Millerbbf1a742012-07-17 18:30:30 -0700643 public void onReceive(Context context, Intent intent) {
644 final String action = intent.getAction();
645 if (DEBUG) Log.d(TAG, "received broadcast " + action);
646
647 if (Intent.ACTION_TIME_TICK.equals(action)
648 || Intent.ACTION_TIME_CHANGED.equals(action)
Adrian Roos48c796c2014-09-01 14:59:23 +0200649 || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700650 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Jim Millerbbf1a742012-07-17 18:30:30 -0700651 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
652 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
653 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
654 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
655 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
Adrian Roos0c859ae2015-11-23 16:47:50 -0800656
657 final int maxChargingMicroAmp = intent.getIntExtra(EXTRA_MAX_CHARGING_CURRENT, -1);
658 int maxChargingMicroVolt = intent.getIntExtra(EXTRA_MAX_CHARGING_VOLTAGE, -1);
659 final int maxChargingMicroWatt;
660
661 if (maxChargingMicroVolt <= 0) {
662 maxChargingMicroVolt = DEFAULT_CHARGING_VOLTAGE_MICRO_VOLT;
663 }
664 if (maxChargingMicroAmp > 0) {
665 // Calculating muW = muA * muV / (10^6 mu^2 / mu); splitting up the divisor
666 // to maintain precision equally on both factors.
667 maxChargingMicroWatt = (maxChargingMicroAmp / 1000)
668 * (maxChargingMicroVolt / 1000);
669 } else {
670 maxChargingMicroWatt = -1;
671 }
Jim Millerbbf1a742012-07-17 18:30:30 -0700672 final Message msg = mHandler.obtainMessage(
Adrian Roos7b043112015-07-10 13:00:33 -0700673 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health,
Adrian Roos0c859ae2015-11-23 16:47:50 -0800674 maxChargingMicroWatt));
Jim Millerbbf1a742012-07-17 18:30:30 -0700675 mHandler.sendMessage(msg);
676 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Jim Miller52a61332014-11-12 19:29:51 -0800677 SimData args = SimData.fromIntent(intent);
Jim Millerbbf1a742012-07-17 18:30:30 -0700678 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -0800679 Log.v(TAG, "action " + action
680 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
681 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -0700682 }
Jim Miller52a61332014-11-12 19:29:51 -0800683 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
684 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -0700685 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
686 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
687 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
688 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
689 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
690 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Jason Monk052082c2015-06-11 11:35:23 -0400691 } else if (Intent.ACTION_AIRPLANE_MODE_CHANGED.equals(action)) {
692 mHandler.sendEmptyMessage(MSG_AIRPLANE_MODE_CHANGED);
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800693 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700694 dispatchBootCompleted();
Etan Cohen47051d82015-07-06 16:19:04 -0700695 } else if (TelephonyIntents.ACTION_SERVICE_STATE_CHANGED.equals(action)) {
696 ServiceState serviceState = ServiceState.newFromBundle(intent.getExtras());
697 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
698 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
699 if (DEBUG) {
700 Log.v(TAG, "action " + action + " serviceState=" + serviceState + " subId="
701 + subId);
702 }
703 mHandler.sendMessage(
704 mHandler.obtainMessage(MSG_SERVICE_STATE_CHANGE, subId, 0, serviceState));
Jim Millerbbf1a742012-07-17 18:30:30 -0700705 }
706 }
707 };
Jim Miller2de5ee82012-06-14 22:22:50 -0700708
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700709 private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
710
Jim Millerd72d5ac2015-09-29 18:55:32 -0700711 @Override
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700712 public void onReceive(Context context, Intent intent) {
713 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +0200714 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
715 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
716 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700717 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
718 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +0200719 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700720 Trace.beginSection("KeyguardUpdateMonitor.mBroadcastAllReceiver#onReceive ACTION_FACE_UNLOCK_STARTED");
Adrian Roos48c796c2014-09-01 14:59:23 +0200721 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
722 getSendingUserId()));
Nick Desaulniers1d396752016-07-25 15:05:33 -0700723 Trace.endSection();
Adrian Roos48c796c2014-09-01 14:59:23 +0200724 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
725 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
726 getSendingUserId()));
727 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
728 .equals(action)) {
729 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -0700730 } else if (ACTION_USER_UNLOCKED.equals(action)) {
731 mHandler.sendEmptyMessage(MSG_USER_UNLOCKED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700732 }
733 }
734 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700735
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700736 private final BroadcastReceiver mStrongAuthTimeoutReceiver = new BroadcastReceiver() {
737 @Override
738 public void onReceive(Context context, Intent intent) {
739 if (ACTION_STRONG_AUTH_TIMEOUT.equals(intent.getAction())) {
740 int userId = intent.getIntExtra(USER_ID, -1);
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700741 mStrongAuthNotTimedOut.remove(userId);
742 notifyStrongAuthStateChanged(userId);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -0700743 }
744 }
745 };
746
Jorim Jaggi3a464782015-08-28 16:59:13 -0700747 private final FingerprintManager.LockoutResetCallback mLockoutResetCallback
748 = new FingerprintManager.LockoutResetCallback() {
749 @Override
750 public void onLockoutReset() {
751 handleFingerprintLockoutReset();
752 }
753 };
754
Jim Miller9f0753f2015-03-23 23:59:22 -0700755 private FingerprintManager.AuthenticationCallback mAuthenticationCallback
756 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -0700757
758 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -0700759 public void onAuthenticationFailed() {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700760 handleFingerprintAuthFailed();
Jim Millerce7eb6d2015-04-03 19:29:13 -0700761 };
762
763 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700764 public void onAuthenticationSucceeded(AuthenticationResult result) {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700765 Trace.beginSection("KeyguardUpdateMonitor#onAuthenticationSucceeded");
Jim Miller837fa7e2016-08-08 20:16:22 -0700766 handleFingerprintAuthenticated(result.getUserId());
Nick Desaulniers1d396752016-07-25 15:05:33 -0700767 Trace.endSection();
Jim Millerf41fc962014-06-18 16:33:51 -0700768 }
769
770 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700771 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700772 handleFingerprintHelp(helpMsgId, helpString.toString());
Jim Miller9f0753f2015-03-23 23:59:22 -0700773 }
774
775 @Override
776 public void onAuthenticationError(int errMsgId, CharSequence errString) {
Jorim Jaggi4cfdcf52015-07-09 12:13:59 -0700777 handleFingerprintError(errMsgId, errString.toString());
778 }
779
780 @Override
781 public void onAuthenticationAcquired(int acquireInfo) {
782 handleFingerprintAcquired(acquireInfo);
Jim Millerf41fc962014-06-18 16:33:51 -0700783 }
784 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700785 private CancellationSignal mFingerprintCancelSignal;
786 private FingerprintManager mFpm;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700787
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800788 /**
Jim Miller47088bb2009-11-24 00:40:16 -0800789 * When we receive a
790 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -0700791 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800792 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -0800793 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800794 */
Jim Miller52a61332014-11-12 19:29:51 -0800795 private static class SimData {
796 public State simState;
797 public int slotId;
798 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800799
Jim Miller52a61332014-11-12 19:29:51 -0800800 SimData(State state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -0800801 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -0800802 slotId = slot;
803 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -0800804 }
805
Jim Miller52a61332014-11-12 19:29:51 -0800806 static SimData fromIntent(Intent intent) {
807 State state;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800808 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
809 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
810 }
Wink Savillea639b312012-07-10 12:37:54 -0700811 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
Jim Miller52a61332014-11-12 19:29:51 -0800812 int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0);
813 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
Wink Savilled09c4ca2014-11-22 10:08:16 -0800814 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea639b312012-07-10 12:37:54 -0700815 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -0700816 final String absentReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700817 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -0700818
Wink Savillea639b312012-07-10 12:37:54 -0700819 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -0700820 absentReason)) {
Wink Savillea639b312012-07-10 12:37:54 -0700821 state = IccCardConstants.State.PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -0700822 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700823 state = IccCardConstants.State.ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -0700824 }
Wink Savillea639b312012-07-10 12:37:54 -0700825 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
826 state = IccCardConstants.State.READY;
827 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800828 final String lockedReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700829 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
830 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
831 state = IccCardConstants.State.PIN_REQUIRED;
832 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
833 state = IccCardConstants.State.PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800834 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700835 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800836 }
Wink Savillea639b312012-07-10 12:37:54 -0700837 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
838 state = IccCardConstants.State.NETWORK_LOCKED;
Jim Miller109f1fd2012-09-19 20:44:16 -0700839 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
840 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
841 // This is required because telephony doesn't return to "READY" after
842 // these state transitions. See bug 7197471.
843 state = IccCardConstants.State.READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800844 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700845 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800846 }
Jim Miller52a61332014-11-12 19:29:51 -0800847 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800848 }
849
Jim Millerd72d5ac2015-09-29 18:55:32 -0700850 @Override
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800851 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -0800852 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800853 }
854 }
855
Adrian Roos12c1ef52014-06-04 13:54:08 +0200856 public static class BatteryStatus {
Adrian Roos7b043112015-07-10 13:00:33 -0700857 public static final int CHARGING_UNKNOWN = -1;
858 public static final int CHARGING_SLOWLY = 0;
859 public static final int CHARGING_REGULAR = 1;
860 public static final int CHARGING_FAST = 2;
861
Jim Miller16464b82011-10-20 21:10:13 -0700862 public final int status;
863 public final int level;
864 public final int plugged;
865 public final int health;
Adrian Roos0c859ae2015-11-23 16:47:50 -0800866 public final int maxChargingWattage;
867 public BatteryStatus(int status, int level, int plugged, int health,
868 int maxChargingWattage) {
Jim Miller16464b82011-10-20 21:10:13 -0700869 this.status = status;
870 this.level = level;
871 this.plugged = plugged;
872 this.health = health;
Adrian Roos0c859ae2015-11-23 16:47:50 -0800873 this.maxChargingWattage = maxChargingWattage;
Jim Miller16464b82011-10-20 21:10:13 -0700874 }
875
Jim Millerbbf1a742012-07-17 18:30:30 -0700876 /**
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700877 * Determine whether the device is plugged in (USB, power, or wireless).
Jim Millerbbf1a742012-07-17 18:30:30 -0700878 * @return true if the device is plugged in.
879 */
Adrian Roosad3bc7f2014-10-30 18:29:38 +0100880 public boolean isPluggedIn() {
Jim Millerbbf1a742012-07-17 18:30:30 -0700881 return plugged == BatteryManager.BATTERY_PLUGGED_AC
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700882 || plugged == BatteryManager.BATTERY_PLUGGED_USB
883 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Jim Millerbbf1a742012-07-17 18:30:30 -0700884 }
885
886 /**
887 * Whether or not the device is charged. Note that some devices never return 100% for
888 * battery level, so this allows either battery level or status to determine if the
889 * battery is charged.
890 * @return true if the device is charged
891 */
892 public boolean isCharged() {
893 return status == BATTERY_STATUS_FULL || level >= 100;
894 }
895
896 /**
897 * Whether battery is low and needs to be charged.
898 * @return true if battery is low
899 */
900 public boolean isBatteryLow() {
901 return level < LOW_BATTERY_THRESHOLD;
902 }
903
Adrian Roos7b043112015-07-10 13:00:33 -0700904 public final int getChargingSpeed(int slowThreshold, int fastThreshold) {
Adrian Roos0c859ae2015-11-23 16:47:50 -0800905 return maxChargingWattage <= 0 ? CHARGING_UNKNOWN :
906 maxChargingWattage < slowThreshold ? CHARGING_SLOWLY :
907 maxChargingWattage > fastThreshold ? CHARGING_FAST :
Adrian Roos7b043112015-07-10 13:00:33 -0700908 CHARGING_REGULAR;
909 }
Jim Miller16464b82011-10-20 21:10:13 -0700910 }
911
Adrian Roosb5e47222015-08-14 15:53:06 -0700912 public class StrongAuthTracker extends LockPatternUtils.StrongAuthTracker {
Rakesh Iyera7aa4d62016-01-19 17:27:23 -0800913 public StrongAuthTracker(Context context) {
914 super(context);
915 }
Adrian Roosb5e47222015-08-14 15:53:06 -0700916
917 public boolean isUnlockingWithFingerprintAllowed() {
918 int userId = getCurrentUser();
919 return isFingerprintAllowedForUser(userId);
920 }
921
922 public boolean hasUserAuthenticatedSinceBoot() {
923 int userId = getCurrentUser();
924 return (getStrongAuthForUser(userId)
925 & STRONG_AUTH_REQUIRED_AFTER_BOOT) == 0;
926 }
927
928 @Override
929 public void onStrongAuthRequiredChanged(int userId) {
Adrian Roos1de8bcb2015-08-19 16:52:52 -0700930 notifyStrongAuthStateChanged(userId);
Adrian Roosb5e47222015-08-14 15:53:06 -0700931 }
932 }
933
Jim Millerdcb3d842012-08-23 19:18:12 -0700934 public static KeyguardUpdateMonitor getInstance(Context context) {
935 if (sInstance == null) {
936 sInstance = new KeyguardUpdateMonitor(context);
937 }
938 return sInstance;
939 }
940
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700941 protected void handleStartedWakingUp() {
Nick Desaulniers1d396752016-07-25 15:05:33 -0700942 Trace.beginSection("KeyguardUpdateMonitor#handleStartedWakingUp");
Jorim Jaggi864e64b2015-05-20 14:13:23 -0700943 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -0700944 final int count = mCallbacks.size();
945 for (int i = 0; i < count; i++) {
946 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
947 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700948 cb.onStartedWakingUp();
Jim Miller20daffd2013-10-07 14:59:53 -0700949 }
950 }
Nick Desaulniers1d396752016-07-25 15:05:33 -0700951 Trace.endSection();
Jim Miller20daffd2013-10-07 14:59:53 -0700952 }
953
Jorim Jaggi95e40382015-09-16 15:53:42 -0700954 protected void handleStartedGoingToSleep(int arg1) {
Jim Millerf41fc962014-06-18 16:33:51 -0700955 clearFingerprintRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -0700956 final int count = mCallbacks.size();
957 for (int i = 0; i < count; i++) {
958 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
959 if (cb != null) {
Jorim Jaggi95e40382015-09-16 15:53:42 -0700960 cb.onStartedGoingToSleep(arg1);
961 }
962 }
963 mGoingToSleep = true;
964 mFingerprintAlreadyAuthenticated = false;
965 updateFingerprintListeningState();
966 }
967
968 protected void handleFinishedGoingToSleep(int arg1) {
969 mGoingToSleep = false;
970 final int count = mCallbacks.size();
971 for (int i = 0; i < count; i++) {
972 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
973 if (cb != null) {
Jorim Jaggi0d210f62015-07-10 14:24:44 -0700974 cb.onFinishedGoingToSleep(arg1);
Jim Miller20daffd2013-10-07 14:59:53 -0700975 }
976 }
Jorim Jaggiea657062015-04-28 13:45:11 -0700977 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -0700978 }
979
Jorim Jaggif1518da2015-07-30 11:56:36 -0700980 private void handleScreenTurnedOn() {
981 final int count = mCallbacks.size();
982 for (int i = 0; i < count; i++) {
983 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
984 if (cb != null) {
985 cb.onScreenTurnedOn();
986 }
987 }
988 }
989
990 private void handleScreenTurnedOff() {
991 final int count = mCallbacks.size();
992 for (int i = 0; i < count; i++) {
993 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
994 if (cb != null) {
995 cb.onScreenTurnedOff();
996 }
997 }
998 }
999
Selim Cinek99415392016-09-09 14:58:41 -07001000 private void handleDreamingStateChanged(int dreamStart) {
1001 final int count = mCallbacks.size();
1002 boolean showingDream = dreamStart == 1;
1003 for (int i = 0; i < count; i++) {
1004 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1005 if (cb != null) {
1006 cb.onDreamingStateChanged(showingDream);
1007 }
1008 }
1009 }
1010
Adam Powell43a372f2013-09-27 17:43:53 -07001011 /**
1012 * IMPORTANT: Must be called from UI thread.
1013 */
1014 public void dispatchSetBackground(Bitmap bmp) {
1015 if (DEBUG) Log.d(TAG, "dispatchSetBackground");
1016 final int count = mCallbacks.size();
1017 for (int i = 0; i < count; i++) {
1018 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1019 if (cb != null) {
1020 cb.onSetBackground(bmp);
1021 }
1022 }
1023 }
1024
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001025 private void handleUserInfoChanged(int userId) {
1026 for (int i = 0; i < mCallbacks.size(); i++) {
1027 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1028 if (cb != null) {
1029 cb.onUserInfoChanged(userId);
1030 }
1031 }
1032 }
1033
Jorim Jaggidadafd42016-09-30 07:20:25 -07001034 private void handleUserUnlocked() {
1035 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1036 for (int i = 0; i < mCallbacks.size(); i++) {
1037 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1038 if (cb != null) {
1039 cb.onUserUnlocked();
1040 }
1041 }
1042 }
1043
Jim Millerdcb3d842012-08-23 19:18:12 -07001044 private KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001045 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -08001046 mSubscriptionManager = SubscriptionManager.from(context);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001047 mAlarmManager = context.getSystemService(AlarmManager.class);
Michael Jurkafff56142012-11-28 16:51:00 -08001048 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Rakesh Iyera7aa4d62016-01-19 17:27:23 -08001049 mStrongAuthTracker = new StrongAuthTracker(context);
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001050
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001051 // Since device can't be un-provisioned, we only need to register a content observer
1052 // to update mDeviceProvisioned when we are...
1053 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001054 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001055 }
Jim Miller47088bb2009-11-24 00:40:16 -08001056
Jim Millerbbf1a742012-07-17 18:30:30 -07001057 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Adrian Roos7b043112015-07-10 13:00:33 -07001058 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001059
Jim Millerbbf1a742012-07-17 18:30:30 -07001060 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001061 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001062 filter.addAction(Intent.ACTION_TIME_TICK);
1063 filter.addAction(Intent.ACTION_TIME_CHANGED);
1064 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
1065 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
Jason Monk052082c2015-06-11 11:35:23 -04001066 filter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001067 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Etan Cohen47051d82015-07-06 16:19:04 -07001068 filter.addAction(TelephonyIntents.ACTION_SERVICE_STATE_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -08001069 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -08001070 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Jim Millerbbf1a742012-07-17 18:30:30 -07001071 context.registerReceiver(mBroadcastReceiver, filter);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001072
Adam Cohenc276e822012-11-08 13:01:08 -08001073 final IntentFilter bootCompleteFilter = new IntentFilter();
1074 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
1075 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
1076 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter);
1077
Adrian Roos48c796c2014-09-01 14:59:23 +02001078 final IntentFilter allUserFilter = new IntentFilter();
1079 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
1080 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
1081 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
1082 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
1083 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
Jorim Jaggidadafd42016-09-30 07:20:25 -07001084 allUserFilter.addAction(ACTION_USER_UNLOCKED);
Adrian Roos48c796c2014-09-01 14:59:23 +02001085 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -07001086 null, null);
1087
Wink Saville071743f2015-01-12 17:11:04 -08001088 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001089 try {
Sudheer Shankadc589ac2016-11-10 15:30:17 -08001090 ActivityManager.getService().registerUserSwitchObserver(
Sudheer Shanka2c4522c2016-08-27 20:53:28 -07001091 new UserSwitchObserver() {
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001092 @Override
1093 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001094 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001095 newUserId, 0, reply));
1096 }
1097 @Override
1098 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001099 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +02001100 newUserId, 0));
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001101 }
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001102 }, TAG);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001103 } catch (RemoteException e) {
Fyodor Kupolov0b77ef92016-06-20 17:16:52 -07001104 e.rethrowAsRuntimeException();
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001105 }
Adrian Roos46842d92014-03-27 14:58:03 +01001106
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001107 IntentFilter strongAuthTimeoutFilter = new IntentFilter();
1108 strongAuthTimeoutFilter.addAction(ACTION_STRONG_AUTH_TIMEOUT);
1109 context.registerReceiver(mStrongAuthTimeoutReceiver, strongAuthTimeoutFilter,
1110 PERMISSION_SELF, null /* handler */);
Jorim Jaggi237b0612015-05-01 14:28:49 -07001111 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
1112 mTrustManager.registerTrustListener(this);
Adrian Roosb5e47222015-08-14 15:53:06 -07001113 new LockPatternUtils(context).registerStrongAuthTracker(mStrongAuthTracker);
Jim Millerf41fc962014-06-18 16:33:51 -07001114
Jim Miller9f0753f2015-03-23 23:59:22 -07001115 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
Jorim Jaggiea657062015-04-28 13:45:11 -07001116 updateFingerprintListeningState();
Jorim Jaggi3a464782015-08-28 16:59:13 -07001117 if (mFpm != null) {
1118 mFpm.addLockoutResetCallback(mLockoutResetCallback);
1119 }
Jorim Jaggie8fde5d2016-06-30 23:41:37 -07001120
1121 mUserManager = context.getSystemService(UserManager.class);
Jorim Jaggiea657062015-04-28 13:45:11 -07001122 }
1123
1124 private void updateFingerprintListeningState() {
1125 boolean shouldListenForFingerprint = shouldListenForFingerprint();
Jorim Jaggi86bed402015-08-20 18:20:02 -07001126 if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING && !shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001127 stopListeningForFingerprint();
Jorim Jaggi86bed402015-08-20 18:20:02 -07001128 } else if (mFingerprintRunningState != FINGERPRINT_STATE_RUNNING
1129 && shouldListenForFingerprint) {
Jorim Jaggiea657062015-04-28 13:45:11 -07001130 startListeningForFingerprint();
1131 }
1132 }
1133
1134 private boolean shouldListenForFingerprint() {
Jorim Jaggi95e40382015-09-16 15:53:42 -07001135 return (mKeyguardIsVisible || !mDeviceInteractive || mBouncer || mGoingToSleep)
1136 && !mSwitchingUser && !mFingerprintAlreadyAuthenticated
1137 && !isFingerprintDisabled(getCurrentUser());
Jim Miller9f0753f2015-03-23 23:59:22 -07001138 }
1139
Jim Millerce7eb6d2015-04-03 19:29:13 -07001140 private void startListeningForFingerprint() {
Jorim Jaggi86bed402015-08-20 18:20:02 -07001141 if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING) {
1142 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING_RESTARTING);
1143 return;
1144 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001145 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -07001146 int userId = ActivityManager.getCurrentUser();
Jorim Jaggi71448a72015-08-18 19:49:04 -07001147 if (isUnlockWithFingerprintPossible(userId)) {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001148 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001149 mFingerprintCancelSignal.cancel();
1150 }
Jim Millerce7eb6d2015-04-03 19:29:13 -07001151 mFingerprintCancelSignal = new CancellationSignal();
Jim Millerf501b582015-06-03 16:36:31 -07001152 mFpm.authenticate(null, mFingerprintCancelSignal, 0, mAuthenticationCallback, null, userId);
Jorim Jaggi86bed402015-08-20 18:20:02 -07001153 setFingerprintRunningState(FINGERPRINT_STATE_RUNNING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001154 }
1155 }
1156
Jorim Jaggi25b4d4b2015-08-11 15:54:06 -07001157 public boolean isUnlockWithFingerprintPossible(int userId) {
Selim Cinek3122fa82015-06-18 01:38:59 -07001158 return mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
1159 && mFpm.getEnrolledFingerprints(userId).size() > 0;
1160 }
1161
Jorim Jaggiea657062015-04-28 13:45:11 -07001162 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -07001163 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
Jorim Jaggi86bed402015-08-20 18:20:02 -07001164 if (mFingerprintRunningState == FINGERPRINT_STATE_RUNNING) {
Jim Miller9f0753f2015-03-23 23:59:22 -07001165 mFingerprintCancelSignal.cancel();
Jim Millerce7eb6d2015-04-03 19:29:13 -07001166 mFingerprintCancelSignal = null;
Jorim Jaggi86bed402015-08-20 18:20:02 -07001167 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
Jim Miller9f0753f2015-03-23 23:59:22 -07001168 }
Jorim Jaggi86bed402015-08-20 18:20:02 -07001169 if (mFingerprintRunningState == FINGERPRINT_STATE_CANCELLING_RESTARTING) {
1170 setFingerprintRunningState(FINGERPRINT_STATE_CANCELLING);
1171 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001172 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001173
Michael Jurkafff56142012-11-28 16:51:00 -08001174 private boolean isDeviceProvisionedInSettingsDb() {
1175 return Settings.Global.getInt(mContext.getContentResolver(),
1176 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
1177 }
1178
Jim Millerbbf1a742012-07-17 18:30:30 -07001179 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -08001180 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001181 @Override
1182 public void onChange(boolean selfChange) {
1183 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -08001184 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001185 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001186 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001187 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001188 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001189 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001190 };
1191
1192 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -07001193 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -08001194 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -07001195
1196 // prevent a race condition between where we check the flag and where we register the
1197 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -08001198 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -07001199 if (provisioned != mDeviceProvisioned) {
1200 mDeviceProvisioned = provisioned;
1201 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -07001202 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -07001203 }
1204 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001205 }
1206
Jim Millerbbf1a742012-07-17 18:30:30 -07001207 /**
Jorim Jaggid11d1a92016-08-16 16:02:32 -07001208 * Update the state whether Keyguard currently has a lockscreen wallpaper.
1209 *
1210 * @param hasLockscreenWallpaper Whether Keyguard has a lockscreen wallpaper.
1211 */
1212 public void setHasLockscreenWallpaper(boolean hasLockscreenWallpaper) {
1213 if (hasLockscreenWallpaper != mHasLockscreenWallpaper) {
1214 mHasLockscreenWallpaper = hasLockscreenWallpaper;
1215 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1216 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1217 if (cb != null) {
1218 cb.onHasLockscreenWallpaperChanged(hasLockscreenWallpaper);
1219 }
1220 }
1221 }
1222 }
1223
1224 /**
1225 * @return Whether Keyguard has a lockscreen wallpaper.
1226 */
1227 public boolean hasLockscreenWallpaper() {
1228 return mHasLockscreenWallpaper;
1229 }
1230
1231 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001232 * Handle {@link #MSG_DPM_STATE_CHANGED}
1233 */
Jim Millerb0304762012-03-13 20:01:25 -07001234 protected void handleDevicePolicyManagerStateChanged() {
Adrian Roos733b6632015-08-21 14:32:35 -07001235 updateFingerprintListeningState();
Jim Millerdcb3d842012-08-23 19:18:12 -07001236 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1237 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1238 if (cb != null) {
1239 cb.onDevicePolicyManagerStateChanged();
1240 }
Jim Millerb0304762012-03-13 20:01:25 -07001241 }
1242 }
1243
Jim Millerbbf1a742012-07-17 18:30:30 -07001244 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001245 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -07001246 */
Chris Wrenf41c61b2012-11-29 15:19:54 -05001247 protected void handleUserSwitching(int userId, IRemoteCallback reply) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001248 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001249 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1250 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -05001251 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -07001252 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001253 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -07001254 try {
1255 reply.sendResult(null);
1256 } catch (RemoteException e) {
1257 }
Amith Yamasani52c489c2012-03-28 11:42:42 -07001258 }
1259
Jim Millerbbf1a742012-07-17 18:30:30 -07001260 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -05001261 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
1262 */
1263 protected void handleUserSwitchComplete(int userId) {
1264 for (int i = 0; i < mCallbacks.size(); i++) {
1265 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1266 if (cb != null) {
1267 cb.onUserSwitchComplete(userId);
1268 }
1269 }
1270 }
1271
1272 /**
Jim Miller90873d52013-09-26 18:11:38 -07001273 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
1274 * keyguard crashes sometime after boot, then it will never receive this
1275 * broadcast and hence not handle the event. This method is ultimately called by
1276 * PhoneWindowManager in this case.
1277 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +01001278 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001279 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -07001280 }
1281
1282 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001283 * Handle {@link #MSG_BOOT_COMPLETED}
1284 */
1285 protected void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -07001286 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001287 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -08001288 for (int i = 0; i < mCallbacks.size(); i++) {
1289 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1290 if (cb != null) {
1291 cb.onBootCompleted();
1292 }
1293 }
1294 }
1295
1296 /**
Jim Miller5ecd8112013-01-09 18:50:26 -08001297 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -08001298 * destroyed.
1299 */
1300 public boolean hasBootCompleted() {
1301 return mBootCompleted;
1302 }
1303
1304 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001305 * Handle {@link #MSG_DEVICE_PROVISIONED}
1306 */
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001307 protected void handleDeviceProvisioned() {
Jim Millerbbf1a742012-07-17 18:30:30 -07001308 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001309 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1310 if (cb != null) {
1311 cb.onDeviceProvisioned();
1312 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001313 }
Michael Jurkafff56142012-11-28 16:51:00 -08001314 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001315 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -08001316 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
1317 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -07001318 }
1319 }
1320
Jim Millerbbf1a742012-07-17 18:30:30 -07001321 /**
1322 * Handle {@link #MSG_PHONE_STATE_CHANGED}
1323 */
Jim Millerc23024d2010-02-24 15:37:00 -08001324 protected void handlePhoneStateChanged(String newState) {
1325 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001326 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
1327 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
1328 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
1329 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
1330 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
1331 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
1332 }
Jim Millerbbf1a742012-07-17 18:30:30 -07001333 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001334 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1335 if (cb != null) {
1336 cb.onPhoneStateChanged(mPhoneState);
1337 }
Jim Millerc23024d2010-02-24 15:37:00 -08001338 }
1339 }
1340
Jim Millerbbf1a742012-07-17 18:30:30 -07001341 /**
1342 * Handle {@link #MSG_RINGER_MODE_CHANGED}
1343 */
Jim Miller47088bb2009-11-24 00:40:16 -08001344 protected void handleRingerModeChange(int mode) {
1345 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -07001346 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -07001347 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001348 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1349 if (cb != null) {
1350 cb.onRingerModeChanged(mode);
1351 }
Jim Miller47088bb2009-11-24 00:40:16 -08001352 }
1353 }
1354
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001355 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001356 * Handle {@link #MSG_TIME_UPDATE}
1357 */
1358 private void handleTimeUpdate() {
1359 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001360 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001361 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1362 if (cb != null) {
1363 cb.onTimeChanged();
1364 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001365 }
1366 }
1367
1368 /**
1369 * Handle {@link #MSG_BATTERY_UPDATE}
1370 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001371 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001372 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001373 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
1374 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07001375 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001376 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001377 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1378 if (cb != null) {
1379 cb.onRefreshBatteryInfo(status);
1380 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001381 }
1382 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001383 }
1384
1385 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001386 * Handle {@link #MSG_SIM_STATE_CHANGE}
1387 */
Jim Miller52a61332014-11-12 19:29:51 -08001388 private void handleSimStateChange(int subId, int slotId, State state) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001389
Jim Miller52a61332014-11-12 19:29:51 -08001390 if (DEBUG_SIM_STATES) {
1391 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
1392 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001393 }
1394
Wink Savillea54bf652014-12-11 13:37:50 -08001395 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08001396 Log.w(TAG, "invalid subId in handleSimStateChange()");
1397 return;
1398 }
1399
1400 SimData data = mSimDatas.get(subId);
1401 final boolean changed;
1402 if (data == null) {
1403 data = new SimData(state, slotId, subId);
1404 mSimDatas.put(subId, data);
1405 changed = true; // no data yet; force update
1406 } else {
1407 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
1408 data.simState = state;
1409 data.subId = subId;
1410 data.slotId = slotId;
1411 }
1412 if (changed && state != State.UNKNOWN) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001413 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001414 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1415 if (cb != null) {
Jim Miller52a61332014-11-12 19:29:51 -08001416 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07001417 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001418 }
1419 }
1420 }
1421
Jim Millerbbf1a742012-07-17 18:30:30 -07001422 /**
Etan Cohen47051d82015-07-06 16:19:04 -07001423 * Handle {@link #MSG_SERVICE_STATE_CHANGE}
1424 */
1425 private void handleServiceStateChange(int subId, ServiceState serviceState) {
1426 if (DEBUG) {
1427 Log.d(TAG,
1428 "handleServiceStateChange(subId=" + subId + ", serviceState=" + serviceState);
1429 }
1430
1431 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
1432 Log.w(TAG, "invalid subId in handleServiceStateChange()");
1433 return;
1434 }
1435
1436 mServiceStates.put(subId, serviceState);
1437
1438 for (int j = 0; j < mCallbacks.size(); j++) {
1439 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
1440 if (cb != null) {
1441 cb.onRefreshCarrierInfo();
1442 }
1443 }
1444 }
1445
1446 /**
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001447 * Notifies that the visibility state of Keyguard has changed.
1448 *
1449 * <p>Needs to be called from the main thread.
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001450 */
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001451 public void onKeyguardVisibilityChanged(boolean showing) {
1452 if (DEBUG) Log.d(TAG, "onKeyguardVisibilityChanged(" + showing + ")");
1453 mKeyguardIsVisible = showing;
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001454 for (int i = 0; i < mCallbacks.size(); i++) {
1455 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1456 if (cb != null) {
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001457 cb.onKeyguardVisibilityChangedRaw(showing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001458 }
1459 }
Jorim Jaggi6a15d522015-09-22 15:55:33 -07001460 if (!showing) {
Jorim Jaggi71448a72015-08-18 19:49:04 -07001461 mFingerprintAlreadyAuthenticated = false;
1462 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001463 updateFingerprintListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001464 }
1465
Brian Colonna7fce3802013-09-17 15:51:32 -04001466 /**
Selim Cinek1fcafc42015-07-20 14:39:25 -07001467 * Handle {@link #MSG_KEYGUARD_RESET}
1468 */
1469 private void handleKeyguardReset() {
1470 if (DEBUG) Log.d(TAG, "handleKeyguardReset");
Adrian Roosf6d51ac2015-09-02 13:26:25 -07001471 updateFingerprintListeningState();
Jorim Jaggi031f7952016-09-01 16:39:26 -07001472 mNeedsSlowUnlockTransition = resolveNeedsSlowUnlockTransition();
1473 }
1474
1475 private boolean resolveNeedsSlowUnlockTransition() {
1476 if (mUserManager.isUserUnlocked(getCurrentUser())) {
1477 return false;
1478 }
1479 Intent homeIntent = new Intent(Intent.ACTION_MAIN)
1480 .addCategory(Intent.CATEGORY_HOME);
1481 ResolveInfo resolveInfo = mContext.getPackageManager().resolveActivity(homeIntent,
1482 0 /* flags */);
1483 return FALLBACK_HOME_COMPONENT.equals(resolveInfo.getComponentInfo().getComponentName());
Selim Cinek1fcafc42015-07-20 14:39:25 -07001484 }
1485
1486 /**
Adrian Roosb6011622014-05-14 15:52:53 +02001487 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
1488 * @see #sendKeyguardBouncerChanged(boolean)
1489 */
1490 private void handleKeyguardBouncerChanged(int bouncer) {
1491 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
1492 boolean isBouncer = (bouncer == 1);
1493 mBouncer = isBouncer;
1494 for (int i = 0; i < mCallbacks.size(); i++) {
1495 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1496 if (cb != null) {
1497 cb.onKeyguardBouncerChanged(isBouncer);
1498 }
1499 }
Jorim Jaggi3cf7eef2015-09-10 14:36:19 -07001500 updateFingerprintListeningState();
Adrian Roosb6011622014-05-14 15:52:53 +02001501 }
1502
1503 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04001504 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
1505 */
1506 private void handleReportEmergencyCallAction() {
1507 for (int i = 0; i < mCallbacks.size(); i++) {
1508 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1509 if (cb != null) {
1510 cb.onEmergencyCallAction();
1511 }
1512 }
1513 }
1514
Jim Miller16464b82011-10-20 21:10:13 -07001515 private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001516 final boolean nowPluggedIn = current.isPluggedIn();
1517 final boolean wasPluggedIn = old.isPluggedIn();
Jim Miller79a444a2011-02-15 15:02:11 -08001518 final boolean stateChangedWhilePluggedIn =
Jim Miller16464b82011-10-20 21:10:13 -07001519 wasPluggedIn == true && nowPluggedIn == true
1520 && (old.status != current.status);
1521
1522 // change in plug state is always interesting
1523 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001524 return true;
1525 }
1526
1527 // change in battery level while plugged in
Jim Miller16464b82011-10-20 21:10:13 -07001528 if (nowPluggedIn && old.level != current.level) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001529 return true;
1530 }
1531
Jim Miller16464b82011-10-20 21:10:13 -07001532 // change where battery needs charging
Jim Millerbbf1a742012-07-17 18:30:30 -07001533 if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
Jim Miller16464b82011-10-20 21:10:13 -07001534 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001535 }
Adrian Roos76dc5a52015-07-21 16:20:36 -07001536
1537 // change in charging current while plugged in
Adrian Roos0c859ae2015-11-23 16:47:50 -08001538 if (nowPluggedIn && current.maxChargingWattage != old.maxChargingWattage) {
Adrian Roos76dc5a52015-07-21 16:20:36 -07001539 return true;
1540 }
1541
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001542 return false;
1543 }
1544
1545 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001546 * Remove the given observer's callback.
1547 *
Jim Miller6212cc02012-09-05 17:35:31 -07001548 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001549 */
Jim Miller6212cc02012-09-05 17:35:31 -07001550 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
1551 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
1552 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1553 if (mCallbacks.get(i).get() == callback) {
1554 mCallbacks.remove(i);
1555 }
1556 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001557 }
1558
1559 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001560 * Register to receive notifications about general keyguard information
1561 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07001562 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001563 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001564 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Jim Miller6212cc02012-09-05 17:35:31 -07001565 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
1566 // Prevent adding duplicate callbacks
1567 for (int i = 0; i < mCallbacks.size(); i++) {
1568 if (mCallbacks.get(i).get() == callback) {
1569 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
1570 new Exception("Called by"));
1571 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07001572 }
1573 }
Jim Miller6212cc02012-09-05 17:35:31 -07001574 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
1575 removeCallback(null); // remove unused references
1576 sendUpdates(callback);
1577 }
1578
Evan Rosky18396452016-07-27 15:19:37 -07001579 public boolean isSwitchingUser() {
1580 return mSwitchingUser;
1581 }
1582
1583 public void setSwitchingUser(boolean switching) {
1584 mSwitchingUser = switching;
1585 updateFingerprintListeningState();
1586 }
1587
Jim Miller6212cc02012-09-05 17:35:31 -07001588 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
1589 // Notify listener of the current state
1590 callback.onRefreshBatteryInfo(mBatteryStatus);
1591 callback.onTimeChanged();
1592 callback.onRingerModeChanged(mRingMode);
1593 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05001594 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07001595 callback.onClockVisibilityChanged();
Jim Miller52a61332014-11-12 19:29:51 -08001596 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
1597 final SimData state = data.getValue();
1598 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
1599 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001600 }
1601
Selim Cinek1fcafc42015-07-20 14:39:25 -07001602 public void sendKeyguardReset() {
1603 mHandler.obtainMessage(MSG_KEYGUARD_RESET).sendToTarget();
1604 }
1605
Adrian Roosb6011622014-05-14 15:52:53 +02001606 /**
1607 * @see #handleKeyguardBouncerChanged(int)
1608 */
1609 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
1610 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
1611 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
1612 message.arg1 = showingBouncer ? 1 : 0;
1613 message.sendToTarget();
1614 }
1615
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001616 /**
Jim Miller90d5d462011-11-17 16:57:01 -08001617 * 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 -08001618 * have the information earlier than waiting for the intent
1619 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08001620 *
1621 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
1622 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001623 */
Jim Miller52a61332014-11-12 19:29:51 -08001624 public void reportSimUnlocked(int subId) {
1625 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
1626 int slotId = SubscriptionManager.getSlotId(subId);
1627 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001628 }
1629
Brian Colonna7fce3802013-09-17 15:51:32 -04001630 /**
1631 * Report that the emergency call button has been pressed and the emergency dialer is
1632 * about to be displayed.
1633 *
1634 * @param bypassHandler runs immediately.
1635 *
1636 * NOTE: Must be called from UI thread if bypassHandler == true.
1637 */
1638 public void reportEmergencyCallAction(boolean bypassHandler) {
1639 if (!bypassHandler) {
1640 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
1641 } else {
1642 handleReportEmergencyCallAction();
1643 }
1644 }
1645
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001646 /**
1647 * @return Whether the device is provisioned (whether they have gone through
1648 * the setup wizard)
1649 */
1650 public boolean isDeviceProvisioned() {
1651 return mDeviceProvisioned;
1652 }
1653
Jorim Jaggi9f743032015-05-04 15:22:40 -07001654 public void clearFailedUnlockAttempts() {
1655 mFailedAttempts.delete(sCurrentUser);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001656 }
1657
Xiyuan Xiace64cea2016-01-06 08:51:16 -08001658 public int getFailedUnlockAttempts(int userId) {
1659 return mFailedAttempts.get(userId, 0);
Jorim Jaggi9f743032015-05-04 15:22:40 -07001660 }
1661
Xiyuan Xiace64cea2016-01-06 08:51:16 -08001662 public void reportFailedStrongAuthUnlockAttempt(int userId) {
1663 mFailedAttempts.put(userId, getFailedUnlockAttempts(userId) + 1);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001664 }
1665
Jim Millerf41fc962014-06-18 16:33:51 -07001666 public void clearFingerprintRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07001667 mUserFingerprintAuthenticated.clear();
Jim Millerf41fc962014-06-18 16:33:51 -07001668 }
1669
Jim Miller52a61332014-11-12 19:29:51 -08001670 public boolean isSimPinVoiceSecure() {
1671 // TODO: only count SIMs that handle voice
1672 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07001673 }
1674
1675 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08001676 // True if any SIM is pin secure
1677 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
1678 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
1679 }
1680 return false;
1681 }
1682
Jason Monk9ff69bd2014-12-02 16:43:17 -05001683 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08001684 if (mSimDatas.containsKey(subId)) {
1685 return mSimDatas.get(subId).simState;
1686 } else {
1687 return State.UNKNOWN;
1688 }
1689 }
1690
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001691 /**
1692 * @return true if and only if the state has changed for the specified {@code slotId}
1693 */
1694 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08001695
1696 // This is awful. It exists because there are two APIs for getting the SIM status
1697 // that don't return the complete set of values and have different types. In Keyguard we
1698 // need IccCardConstants, but TelephonyManager would only give us
1699 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08001700 final TelephonyManager tele = TelephonyManager.from(mContext);
1701 int simState = tele.getSimState(slotId);
Jim Miller52a61332014-11-12 19:29:51 -08001702 State state;
1703 try {
xinhe18b9c3c2014-12-02 15:03:20 -08001704 state = State.intToState(simState);
Jim Miller52a61332014-11-12 19:29:51 -08001705 } catch(IllegalArgumentException ex) {
xinhe18b9c3c2014-12-02 15:03:20 -08001706 Log.w(TAG, "Unknown sim state: " + simState);
Jim Miller52a61332014-11-12 19:29:51 -08001707 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05001708 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001709 SimData data = mSimDatas.get(subId);
1710 final boolean changed;
1711 if (data == null) {
1712 data = new SimData(state, slotId, subId);
1713 mSimDatas.put(subId, data);
1714 changed = true; // no data yet; force update
1715 } else {
1716 changed = data.simState != state;
1717 data.simState = state;
1718 }
1719 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07001720 }
1721
1722 public static boolean isSimPinSecure(IccCardConstants.State state) {
1723 final IccCardConstants.State simState = state;
1724 return (simState == IccCardConstants.State.PIN_REQUIRED
1725 || simState == IccCardConstants.State.PUK_REQUIRED
1726 || simState == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07001727 }
Jim Miller8f09fd22013-03-14 19:04:28 -07001728
1729 public DisplayClientState getCachedDisplayClientState() {
1730 return mDisplayClientState;
1731 }
Jim Miller20daffd2013-10-07 14:59:53 -07001732
1733 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
1734 // (KeyguardViewMediator, KeyguardHostView)
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001735 public void dispatchStartedWakingUp() {
1736 synchronized (this) {
1737 mDeviceInteractive = true;
1738 }
1739 mHandler.sendEmptyMessage(MSG_STARTED_WAKING_UP);
1740 }
1741
Jorim Jaggi95e40382015-09-16 15:53:42 -07001742 public void dispatchStartedGoingToSleep(int why) {
1743 mHandler.sendMessage(mHandler.obtainMessage(MSG_STARTED_GOING_TO_SLEEP, why, 0));
1744 }
1745
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001746 public void dispatchFinishedGoingToSleep(int why) {
1747 synchronized(this) {
1748 mDeviceInteractive = false;
1749 }
1750 mHandler.sendMessage(mHandler.obtainMessage(MSG_FINISHED_GOING_TO_SLEEP, why, 0));
1751 }
1752
Jim Miller20daffd2013-10-07 14:59:53 -07001753 public void dispatchScreenTurnedOn() {
1754 synchronized (this) {
1755 mScreenOn = true;
1756 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001757 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
Jim Miller20daffd2013-10-07 14:59:53 -07001758 }
1759
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001760 public void dispatchScreenTurnedOff() {
Jim Miller20daffd2013-10-07 14:59:53 -07001761 synchronized(this) {
1762 mScreenOn = false;
1763 }
Jorim Jaggif1518da2015-07-30 11:56:36 -07001764 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_OFF);
Jim Miller20daffd2013-10-07 14:59:53 -07001765 }
1766
Selim Cinek99415392016-09-09 14:58:41 -07001767 public void dispatchDreamingStarted() {
1768 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 1, 0));
1769 }
1770
1771 public void dispatchDreamingStopped() {
1772 mHandler.sendMessage(mHandler.obtainMessage(MSG_DREAMING_STATE_CHANGED, 0, 0));
1773 }
1774
Jorim Jaggi0d210f62015-07-10 14:24:44 -07001775 public boolean isDeviceInteractive() {
1776 return mDeviceInteractive;
Jim Miller20daffd2013-10-07 14:59:53 -07001777 }
Jim Miller52a61332014-11-12 19:29:51 -08001778
Jorim Jaggi95e40382015-09-16 15:53:42 -07001779 public boolean isGoingToSleep() {
1780 return mGoingToSleep;
1781 }
1782
Jim Miller52a61332014-11-12 19:29:51 -08001783 /**
1784 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
1785 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08001786 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08001787 */
1788 public int getNextSubIdForState(State state) {
1789 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08001790 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08001791 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
1792 for (int i = 0; i < list.size(); i++) {
1793 final SubscriptionInfo info = list.get(i);
1794 final int id = info.getSubscriptionId();
1795 int slotId = SubscriptionManager.getSlotId(id);
1796 if (state == getSimState(id) && bestSlotId > slotId ) {
1797 resultId = id;
1798 bestSlotId = slotId;
1799 }
1800 }
1801 return resultId;
1802 }
1803
1804 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
1805 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
1806 for (int i = 0; i < list.size(); i++) {
1807 SubscriptionInfo info = list.get(i);
1808 if (subId == info.getSubscriptionId()) return info;
1809 }
1810 return null; // not found
1811 }
Jason Monkab525272015-07-13 17:02:49 -04001812
1813 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
1814 pw.println("KeyguardUpdateMonitor state:");
1815 pw.println(" SIM States:");
1816 for (SimData data : mSimDatas.values()) {
1817 pw.println(" " + data.toString());
1818 }
1819 pw.println(" Subs:");
1820 if (mSubscriptionInfo != null) {
1821 for (int i = 0; i < mSubscriptionInfo.size(); i++) {
1822 pw.println(" " + mSubscriptionInfo.get(i));
1823 }
1824 }
1825 pw.println(" Service states:");
1826 for (int subId : mServiceStates.keySet()) {
1827 pw.println(" " + subId + "=" + mServiceStates.get(subId));
1828 }
Jim Millerd72d5ac2015-09-29 18:55:32 -07001829 if (mFpm != null && mFpm.isHardwareDetected()) {
1830 final int userId = ActivityManager.getCurrentUser();
1831 final int strongAuthFlags = mStrongAuthTracker.getStrongAuthForUser(userId);
1832 pw.println(" Fingerprint state (user=" + userId + ")");
1833 pw.println(" allowed=" + isUnlockingWithFingerprintAllowed());
1834 pw.println(" auth'd=" + mUserFingerprintAuthenticated.get(userId));
1835 pw.println(" authSinceBoot="
1836 + getStrongAuthTracker().hasUserAuthenticatedSinceBoot());
1837 pw.println(" disabled(DPM)=" + isFingerprintDisabled(userId));
1838 pw.println(" possible=" + isUnlockWithFingerprintPossible(userId));
1839 pw.println(" strongAuthFlags=" + Integer.toHexString(strongAuthFlags));
1840 pw.println(" timedout=" + hasFingerprintUnlockTimedOut(userId));
1841 pw.println(" trustManaged=" + getUserTrustIsManaged(userId));
1842 }
Jason Monkab525272015-07-13 17:02:49 -04001843 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001844}