blob: d13d71c5bf8a5ce5a15e5cb5854dbbe3cf878741 [file] [log] [blame]
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Jim Miller5ecd8112013-01-09 18:50:26 -080017package com.android.keyguard;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080018
Jorim Jaggiccdfa932015-04-13 16:29:48 -070019import android.app.ActivityManager;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070020import android.app.ActivityManagerNative;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020021import android.app.AlarmManager;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070022import android.app.IUserSwitchObserver;
Jim Miller8f09fd22013-03-14 19:04:28 -070023import android.app.PendingIntent;
Jim Millerb0304762012-03-13 20:01:25 -070024import android.app.admin.DevicePolicyManager;
Adrian Roos46842d92014-03-27 14:58:03 +010025import android.app.trust.TrustManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080026import android.content.BroadcastReceiver;
Jim Millerf41fc962014-06-18 16:33:51 -070027import android.content.ContentResolver;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080028import android.content.Context;
29import android.content.Intent;
30import android.content.IntentFilter;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080031import android.database.ContentObserver;
Jim Miller8f09fd22013-03-14 19:04:28 -070032import android.graphics.Bitmap;
33
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080034import static android.os.BatteryManager.BATTERY_STATUS_FULL;
35import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
Jim Miller16464b82011-10-20 21:10:13 -070036import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
37import static android.os.BatteryManager.EXTRA_STATUS;
38import static android.os.BatteryManager.EXTRA_PLUGGED;
39import static android.os.BatteryManager.EXTRA_LEVEL;
40import static android.os.BatteryManager.EXTRA_HEALTH;
Jim Miller06e34502014-07-17 14:46:05 -070041
Jim Miller47088bb2009-11-24 00:40:16 -080042import android.media.AudioManager;
Jim Miller79a444a2011-02-15 15:02:11 -080043import android.os.BatteryManager;
Jim Miller9f0753f2015-03-23 23:59:22 -070044import android.os.CancellationSignal;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080045import android.os.Handler;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070046import android.os.IRemoteCallback;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080047import android.os.Message;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070048import android.os.RemoteException;
Amith Yamasanie8e93a12013-05-09 18:12:30 -070049import android.os.UserHandle;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080050import android.provider.Settings;
Dianne Hackbornb7e787f2009-05-07 15:55:42 -070051
Wink Savillea639b312012-07-10 12:37:54 -070052import com.android.internal.telephony.IccCardConstants;
Jim Miller52a61332014-11-12 19:29:51 -080053import com.android.internal.telephony.IccCardConstants.State;
54import com.android.internal.telephony.PhoneConstants;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080055import com.android.internal.telephony.TelephonyIntents;
Jim Miller9f0753f2015-03-23 23:59:22 -070056
Jim Millerebbf2052015-03-31 17:24:34 -070057import android.hardware.fingerprint.FingerprintManager;
58import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
59import android.hardware.fingerprint.FingerprintUtils;
60import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
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;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080065import android.util.Log;
Adrian Roos46842d92014-03-27 14:58:03 +010066import android.util.SparseBooleanArray;
Jorim Jaggi9f743032015-05-04 15:22:40 -070067import android.util.SparseIntArray;
Adrian Roos46842d92014-03-27 14:58:03 +010068
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080069import com.google.android.collect.Lists;
70
Jim Millerdcb3d842012-08-23 19:18:12 -070071import java.lang.ref.WeakReference;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080072import java.util.ArrayList;
Jim Miller52a61332014-11-12 19:29:51 -080073import java.util.HashMap;
74import java.util.List;
75import java.util.Map.Entry;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080076
77/**
78 * Watches for updates that may be interesting to the keyguard, and provides
79 * the up to date information as well as a registration for callbacks that care
80 * to be updated.
81 *
82 * Note: under time crunch, this has been extended to include some stuff that
83 * doesn't really belong here. see {@link #handleBatteryUpdate} where it shutdowns
Jim Miller258341c2012-08-30 16:50:10 -070084 * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()}
85 * and {@link #clearFailedUnlockAttempts()}. Maybe we should rename this 'KeyguardContext'...
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080086 */
Adrian Roos46842d92014-03-27 14:58:03 +010087public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080088
Jim Millerbbf1a742012-07-17 18:30:30 -070089 private static final String TAG = "KeyguardUpdateMonitor";
Jorim Jaggi5cf17872014-03-26 18:31:48 +010090 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller52a61332014-11-12 19:29:51 -080091 private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
Jim Millerbbf1a742012-07-17 18:30:30 -070092 private static final int LOW_BATTERY_THRESHOLD = 20;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080093
Jorim Jaggie7b12522014-08-06 16:41:21 +020094 private static final String ACTION_FACE_UNLOCK_STARTED
95 = "com.android.facelock.FACE_UNLOCK_STARTED";
96 private static final String ACTION_FACE_UNLOCK_STOPPED
97 = "com.android.facelock.FACE_UNLOCK_STOPPED";
98
Jim Millerbbf1a742012-07-17 18:30:30 -070099 // Callback messages
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800100 private static final int MSG_TIME_UPDATE = 301;
101 private static final int MSG_BATTERY_UPDATE = 302;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800102 private static final int MSG_SIM_STATE_CHANGE = 304;
Jim Miller47088bb2009-11-24 00:40:16 -0800103 private static final int MSG_RINGER_MODE_CHANGED = 305;
Jim Millerc23024d2010-02-24 15:37:00 -0800104 private static final int MSG_PHONE_STATE_CHANGED = 306;
Jeff Sharkey054340d2011-09-01 22:28:03 -0700105 private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700106 private static final int MSG_DEVICE_PROVISIONED = 308;
Jim Miller57375342012-09-09 15:20:31 -0700107 private static final int MSG_DPM_STATE_CHANGED = 309;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500108 private static final int MSG_USER_SWITCHING = 310;
Danielle Millettf6d0fc12012-10-23 16:16:52 -0400109 private static final int MSG_KEYGUARD_VISIBILITY_CHANGED = 312;
Jim Millerf41fc962014-06-18 16:33:51 -0700110 private static final int MSG_BOOT_COMPLETED = 313;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500111 private static final int MSG_USER_SWITCH_COMPLETE = 314;
Jim Millerf41fc962014-06-18 16:33:51 -0700112 private static final int MSG_USER_INFO_CHANGED = 317;
113 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
Jim Miller20daffd2013-10-07 14:59:53 -0700114 private static final int MSG_SCREEN_TURNED_ON = 319;
115 private static final int MSG_SCREEN_TURNED_OFF = 320;
Adrian Roosb6011622014-05-14 15:52:53 +0200116 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
Jim Miller9f0753f2015-03-23 23:59:22 -0700117 private static final int MSG_FINGERPRINT_AUTHENTICATED = 323;
118 private static final int MSG_FINGERPRINT_ERROR = 324;
119 private static final int MSG_FINGERPRINT_HELP = 325;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700120 private static final int MSG_FINGERPRINT_AUTH_FAILED = 326;
121 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 327;
122 private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 328;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800123
Jim Millerdcb3d842012-08-23 19:18:12 -0700124 private static KeyguardUpdateMonitor sInstance;
125
Jim Millerbbf1a742012-07-17 18:30:30 -0700126 private final Context mContext;
Jim Miller52a61332014-11-12 19:29:51 -0800127 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700128
Jim Millerbbf1a742012-07-17 18:30:30 -0700129 private int mRingMode;
130 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400131 private boolean mKeyguardIsVisible;
Adrian Roosb6011622014-05-14 15:52:53 +0200132 private boolean mBouncer;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800133 private boolean mBootCompleted;
Jim Millerbbf1a742012-07-17 18:30:30 -0700134
Jim Millerdcb3d842012-08-23 19:18:12 -0700135 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700136 private boolean mDeviceProvisioned;
137
Jim Millerdcb3d842012-08-23 19:18:12 -0700138 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700139 private BatteryStatus mBatteryStatus;
140
Jim Millerdcb3d842012-08-23 19:18:12 -0700141 // Password attempts
Jorim Jaggi9f743032015-05-04 15:22:40 -0700142 private SparseIntArray mFailedAttempts = new SparseIntArray();
Brian Colonnacc4104f2012-10-09 17:50:46 -0400143
Jim Millerbbf1a742012-07-17 18:30:30 -0700144 private boolean mClockVisible;
145
Jim Miller6212cc02012-09-05 17:35:31 -0700146 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700147 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800148 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700149
Brian Colonnaa5239892013-04-15 11:45:40 -0400150 private boolean mSwitchingUser;
151
Jim Miller20daffd2013-10-07 14:59:53 -0700152 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800153 private SubscriptionManager mSubscriptionManager;
154 private List<SubscriptionInfo> mSubscriptionInfo;
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700155 private boolean mFingerprintDetectionRunning;
Jorim Jaggi237b0612015-05-01 14:28:49 -0700156 private TrustManager mTrustManager;
Jim Miller20daffd2013-10-07 14:59:53 -0700157
Jim Millerbbf1a742012-07-17 18:30:30 -0700158 private final Handler mHandler = new Handler() {
159 @Override
160 public void handleMessage(Message msg) {
161 switch (msg.what) {
162 case MSG_TIME_UPDATE:
163 handleTimeUpdate();
164 break;
165 case MSG_BATTERY_UPDATE:
166 handleBatteryUpdate((BatteryStatus) msg.obj);
167 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700168 case MSG_SIM_STATE_CHANGE:
Jim Miller52a61332014-11-12 19:29:51 -0800169 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700170 break;
171 case MSG_RINGER_MODE_CHANGED:
172 handleRingerModeChange(msg.arg1);
173 break;
174 case MSG_PHONE_STATE_CHANGED:
Adrian Roosb6011622014-05-14 15:52:53 +0200175 handlePhoneStateChanged((String) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700176 break;
177 case MSG_CLOCK_VISIBILITY_CHANGED:
178 handleClockVisibilityChanged();
179 break;
180 case MSG_DEVICE_PROVISIONED:
181 handleDeviceProvisioned();
182 break;
183 case MSG_DPM_STATE_CHANGED:
184 handleDevicePolicyManagerStateChanged();
185 break;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500186 case MSG_USER_SWITCHING:
Adrian Roosb6011622014-05-14 15:52:53 +0200187 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
Chris Wrenf41c61b2012-11-29 15:19:54 -0500188 break;
189 case MSG_USER_SWITCH_COMPLETE:
190 handleUserSwitchComplete(msg.arg1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700191 break;
Danielle Millettf6d0fc12012-10-23 16:16:52 -0400192 case MSG_KEYGUARD_VISIBILITY_CHANGED:
193 handleKeyguardVisibilityChanged(msg.arg1);
194 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200195 case MSG_KEYGUARD_BOUNCER_CHANGED:
196 handleKeyguardBouncerChanged(msg.arg1);
197 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800198 case MSG_BOOT_COMPLETED:
199 handleBootCompleted();
200 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700201 case MSG_USER_INFO_CHANGED:
202 handleUserInfoChanged(msg.arg1);
203 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400204 case MSG_REPORT_EMERGENCY_CALL_ACTION:
205 handleReportEmergencyCallAction();
206 break;
Jim Miller20daffd2013-10-07 14:59:53 -0700207 case MSG_SCREEN_TURNED_OFF:
208 handleScreenTurnedOff(msg.arg1);
209 break;
210 case MSG_SCREEN_TURNED_ON:
211 handleScreenTurnedOn();
212 break;
Jim Miller9f0753f2015-03-23 23:59:22 -0700213 case MSG_FINGERPRINT_AUTHENTICATED:
214 handleFingerprintAuthenticated(msg.arg1, msg.arg2);
Jim Millerf41fc962014-06-18 16:33:51 -0700215 break;
Jim Miller9f0753f2015-03-23 23:59:22 -0700216 case MSG_FINGERPRINT_HELP:
217 handleFingerprintHelp(msg.arg1 /* msgId */, (String) msg.obj /* errString */);
218 break;
219 case MSG_FINGERPRINT_ERROR:
220 handleFingerprintError(msg.arg1 /* msgId */, (String) msg.obj /* errString */);
Jim Millerf41fc962014-06-18 16:33:51 -0700221 break;
Jim Millerce7eb6d2015-04-03 19:29:13 -0700222 case MSG_FINGERPRINT_AUTH_FAILED:
223 handleFingerprintAuthFailed();
224 break;
Jorim Jaggie7b12522014-08-06 16:41:21 +0200225 case MSG_FACE_UNLOCK_STATE_CHANGED:
Adrian Roos4a410172014-08-20 17:41:44 +0200226 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200227 break;
Jim Miller52a61332014-11-12 19:29:51 -0800228 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
229 handleSimSubscriptionInfoChanged();
230 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700231 }
232 }
233 };
234
Wink Savilled09c4ca2014-11-22 10:08:16 -0800235 private OnSubscriptionsChangedListener mSubscriptionListener =
236 new OnSubscriptionsChangedListener() {
Jim Miller52a61332014-11-12 19:29:51 -0800237 @Override
Wink Savilled09c4ca2014-11-22 10:08:16 -0800238 public void onSubscriptionsChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800239 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
240 }
241 };
242
Adrian Roos46842d92014-03-27 14:58:03 +0100243 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200244 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Jim Miller9f0753f2015-03-23 23:59:22 -0700245 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200246 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100247
Adrian Roosd6aa6cb2015-04-16 19:31:29 -0700248 private static int sCurrentUser;
249
250 public synchronized static void setCurrentUser(int currentUser) {
251 sCurrentUser = currentUser;
252 }
253
254 public synchronized static int getCurrentUser() {
255 return sCurrentUser;
256 }
257
Adrian Roos46842d92014-03-27 14:58:03 +0100258 @Override
Adrian Roos94e15a52015-04-16 12:23:18 -0700259 public void onTrustChanged(boolean enabled, int userId, int flags) {
Adrian Roos46842d92014-03-27 14:58:03 +0100260 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200261 for (int i = 0; i < mCallbacks.size(); i++) {
262 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
263 if (cb != null) {
264 cb.onTrustChanged(userId);
Adrian Roos94e15a52015-04-16 12:23:18 -0700265 if (enabled && flags != 0) {
266 cb.onTrustGrantedWithFlags(flags, userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200267 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200268 }
269 }
Adrian Roos46842d92014-03-27 14:58:03 +0100270 }
271
Jim Miller52a61332014-11-12 19:29:51 -0800272 protected void handleSimSubscriptionInfoChanged() {
273 if (DEBUG_SIM_STATES) {
274 Log.v(TAG, "onSubscriptionInfoChanged()");
Wink Savilled09c4ca2014-11-22 10:08:16 -0800275 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
276 if (sil != null) {
277 for (SubscriptionInfo subInfo : sil) {
278 Log.v(TAG, "SubInfo:" + subInfo);
279 }
280 } else {
281 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800282 }
283 }
284 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
285
286 // Hack level over 9000: Because the subscription id is not yet valid when we see the
287 // first update in handleSimStateChange, we need to force refresh all all SIM states
288 // so the subscription id for them is consistent.
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100289 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
Jim Miller52a61332014-11-12 19:29:51 -0800290 for (int i = 0; i < subscriptionInfos.size(); i++) {
291 SubscriptionInfo info = subscriptionInfos.get(i);
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100292 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
293 if (changed) {
294 changedSubscriptions.add(info);
295 }
Jim Miller52a61332014-11-12 19:29:51 -0800296 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100297 for (int i = 0; i < changedSubscriptions.size(); i++) {
298 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800299 for (int j = 0; j < mCallbacks.size(); j++) {
300 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
301 if (cb != null) {
302 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
303 }
304 }
305 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500306 for (int j = 0; j < mCallbacks.size(); j++) {
307 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
308 if (cb != null) {
309 cb.onRefreshCarrierInfo();
310 }
311 }
Jim Miller52a61332014-11-12 19:29:51 -0800312 }
313
Wink Savilled09c4ca2014-11-22 10:08:16 -0800314 /** @return List of SubscriptionInfo records, maybe empty but never null */
Jim Miller52a61332014-11-12 19:29:51 -0800315 List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800316 List<SubscriptionInfo> sil = mSubscriptionInfo;
317 if (sil == null || forceReload) {
318 sil = mSubscriptionManager.getActiveSubscriptionInfoList();
319 }
320 if (sil == null) {
321 // getActiveSubscriptionInfoList was null callers expect an empty list.
322 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
323 } else {
324 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800325 }
326 return mSubscriptionInfo;
327 }
328
Adrian Roos7861c662014-07-25 15:37:28 +0200329 @Override
330 public void onTrustManagedChanged(boolean managed, int userId) {
331 mUserTrustIsManaged.put(userId, managed);
332
333 for (int i = 0; i < mCallbacks.size(); i++) {
334 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
335 if (cb != null) {
336 cb.onTrustManagedChanged(userId);
337 }
338 }
339 }
340
Jim Miller9f0753f2015-03-23 23:59:22 -0700341 private void onFingerprintAuthenticated(int userId) {
342 mUserFingerprintAuthenticated.put(userId, true);
Jim Millerf41fc962014-06-18 16:33:51 -0700343 for (int i = 0; i < mCallbacks.size(); i++) {
344 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
345 if (cb != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700346 cb.onFingerprintAuthenticated(userId);
Jim Millerf41fc962014-06-18 16:33:51 -0700347 }
348 }
349 }
350
Jim Millerce7eb6d2015-04-03 19:29:13 -0700351 private void handleFingerprintAuthFailed() {
352 // FingerprintManager will allow us to retry a few times before finally giving up.
353 // TODO: Figure out the proper logic to stop this call when max tries is reached.
354 handleFingerprintHelp(-1, mContext.getString(R.string.fingerprint_not_recognized));
355 }
Jim Millerf41fc962014-06-18 16:33:51 -0700356
Jim Millerce7eb6d2015-04-03 19:29:13 -0700357 private void handleFingerprintAuthenticated(int fingerId, int groupId) {
Jim Millerf41fc962014-06-18 16:33:51 -0700358 try {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700359 final int userId;
360 try {
361 userId = ActivityManagerNative.getDefault().getCurrentUser().id;
362 } catch (RemoteException e) {
363 Log.e(TAG, "Failed to get current user id: ", e);
364 return;
Jim Millerf41fc962014-06-18 16:33:51 -0700365 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700366 if (isFingerprintDisabled(userId)) {
367 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
368 return;
369 }
370 final ContentResolver res = mContext.getContentResolver();
371 final int ids[] = FingerprintUtils.getFingerprintIdsForUser(res, userId);
372 for (int i = 0; i < ids.length; i++) {
373 // TODO: fix once HAL supports storing group id
374 final boolean isCorrectUser = true || (groupId == userId);
375 if (ids[i] == fingerId && isCorrectUser) {
376 onFingerprintAuthenticated(userId);
377 }
378 }
379 } finally {
380 setFingerprintRunningDetectionRunning(false);
Jim Millerf41fc962014-06-18 16:33:51 -0700381 }
382 }
383
Jim Miller9f0753f2015-03-23 23:59:22 -0700384 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700385 for (int i = 0; i < mCallbacks.size(); i++) {
386 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
387 if (cb != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700388 cb.onFingerprintHelp(msgId, helpString);
389 }
390 }
391 }
392
393 private void handleFingerprintError(int msgId, String errString) {
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700394 setFingerprintRunningDetectionRunning(false);
Jim Miller9f0753f2015-03-23 23:59:22 -0700395 for (int i = 0; i < mCallbacks.size(); i++) {
396 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
397 if (cb != null) {
398 cb.onFingerprintError(msgId, errString);
Jim Millerf41fc962014-06-18 16:33:51 -0700399 }
400 }
401 }
402
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700403 private void setFingerprintRunningDetectionRunning(boolean running) {
404 if (running != mFingerprintDetectionRunning) {
405 mFingerprintDetectionRunning = running;
406 notifyFingerprintRunningStateChanged();
407 }
408 }
409
410 private void notifyFingerprintRunningStateChanged() {
411 for (int i = 0; i < mCallbacks.size(); i++) {
412 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
413 if (cb != null) {
414 cb.onFingerprintRunningStateChanged(mFingerprintDetectionRunning);
415 }
416 }
417 }
Adrian Roos4a410172014-08-20 17:41:44 +0200418 private void handleFaceUnlockStateChanged(boolean running, int userId) {
419 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200420 for (int i = 0; i < mCallbacks.size(); i++) {
421 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
422 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200423 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200424 }
425 }
426 }
427
Adrian Roos4a410172014-08-20 17:41:44 +0200428 public boolean isFaceUnlockRunning(int userId) {
429 return mUserFaceUnlockRunning.get(userId);
430 }
431
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700432 public boolean isFingerprintDetectionRunning() {
433 return mFingerprintDetectionRunning;
434 }
435
Jim Miller50e62182014-04-23 17:25:00 -0700436 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100437 // Don't allow trust agent if device is secured with a SIM PIN. This is here
438 // mainly because there's no other way to prompt the user to enter their SIM PIN
439 // once they get past the keyguard screen.
440 final boolean disabledBySimPin = isSimPinSecure();
441 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700442 }
443
Jim Miller06e34502014-07-17 14:46:05 -0700444 private boolean isFingerprintDisabled(int userId) {
445 final DevicePolicyManager dpm =
446 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
447 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
448 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0;
449 }
450
Adrian Roos46842d92014-03-27 14:58:03 +0100451 public boolean getUserHasTrust(int userId) {
Jim Millerf41fc962014-06-18 16:33:51 -0700452 return !isTrustDisabled(userId) && mUserHasTrust.get(userId)
Jim Miller9f0753f2015-03-23 23:59:22 -0700453 || mUserFingerprintAuthenticated.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100454 }
455
Adrian Roos7861c662014-07-25 15:37:28 +0200456 public boolean getUserTrustIsManaged(int userId) {
457 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
458 }
459
Jim Miller8f09fd22013-03-14 19:04:28 -0700460 static class DisplayClientState {
461 public int clientGeneration;
462 public boolean clearing;
463 public PendingIntent intent;
464 public int playbackState;
465 public long playbackEventTime;
466 }
467
468 private DisplayClientState mDisplayClientState = new DisplayClientState();
469
Jim Millerbbf1a742012-07-17 18:30:30 -0700470 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
471
472 public void onReceive(Context context, Intent intent) {
473 final String action = intent.getAction();
474 if (DEBUG) Log.d(TAG, "received broadcast " + action);
475
476 if (Intent.ACTION_TIME_TICK.equals(action)
477 || Intent.ACTION_TIME_CHANGED.equals(action)
Adrian Roos48c796c2014-09-01 14:59:23 +0200478 || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700479 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Jim Millerbbf1a742012-07-17 18:30:30 -0700480 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
481 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
482 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
483 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
484 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
485 final Message msg = mHandler.obtainMessage(
486 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health));
487 mHandler.sendMessage(msg);
488 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Jim Miller52a61332014-11-12 19:29:51 -0800489 SimData args = SimData.fromIntent(intent);
Jim Millerbbf1a742012-07-17 18:30:30 -0700490 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -0800491 Log.v(TAG, "action " + action
492 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
493 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -0700494 }
Jim Miller52a61332014-11-12 19:29:51 -0800495 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
496 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -0700497 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
498 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
499 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
500 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
501 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
502 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800503 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700504 dispatchBootCompleted();
Jim Millerbbf1a742012-07-17 18:30:30 -0700505 }
506 }
507 };
Jim Miller2de5ee82012-06-14 22:22:50 -0700508
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700509 private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
510
511 public void onReceive(Context context, Intent intent) {
512 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +0200513 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
514 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
515 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700516 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
517 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +0200518 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
519 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
520 getSendingUserId()));
521 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
522 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
523 getSendingUserId()));
524 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
525 .equals(action)) {
526 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700527 }
528 }
529 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700530
531 private FingerprintManager.AuthenticationCallback mAuthenticationCallback
532 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -0700533
534 @Override
Jim Millerce7eb6d2015-04-03 19:29:13 -0700535 public void onAuthenticationFailed() {
536 mHandler.obtainMessage(MSG_FINGERPRINT_AUTH_FAILED).sendToTarget();
537 };
538
539 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700540 public void onAuthenticationSucceeded(AuthenticationResult result) {
541 mHandler.obtainMessage(MSG_FINGERPRINT_AUTHENTICATED,
542 result.getFingerprint().getFingerId(),
543 result.getFingerprint().getGroupId()).sendToTarget();
Jim Millerf41fc962014-06-18 16:33:51 -0700544 }
545
546 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700547 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
548 mHandler.obtainMessage(MSG_FINGERPRINT_HELP, helpMsgId, 0, helpString).sendToTarget();
549 }
550
551 @Override
552 public void onAuthenticationError(int errMsgId, CharSequence errString) {
Jorim Jaggi570de1e2015-05-01 15:08:34 -0700553 mHandler.obtainMessage(MSG_FINGERPRINT_ERROR, errMsgId, 0, errString).sendToTarget();
Jim Millerf41fc962014-06-18 16:33:51 -0700554 }
555 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700556 private CancellationSignal mFingerprintCancelSignal;
557 private FingerprintManager mFpm;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700558
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800559 /**
Jim Miller47088bb2009-11-24 00:40:16 -0800560 * When we receive a
561 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -0700562 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800563 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -0800564 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800565 */
Jim Miller52a61332014-11-12 19:29:51 -0800566 private static class SimData {
567 public State simState;
568 public int slotId;
569 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800570
Jim Miller52a61332014-11-12 19:29:51 -0800571 SimData(State state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -0800572 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -0800573 slotId = slot;
574 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -0800575 }
576
Jim Miller52a61332014-11-12 19:29:51 -0800577 static SimData fromIntent(Intent intent) {
578 State state;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800579 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
580 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
581 }
Wink Savillea639b312012-07-10 12:37:54 -0700582 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
Jim Miller52a61332014-11-12 19:29:51 -0800583 int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0);
584 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
Wink Savilled09c4ca2014-11-22 10:08:16 -0800585 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea639b312012-07-10 12:37:54 -0700586 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -0700587 final String absentReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700588 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -0700589
Wink Savillea639b312012-07-10 12:37:54 -0700590 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -0700591 absentReason)) {
Wink Savillea639b312012-07-10 12:37:54 -0700592 state = IccCardConstants.State.PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -0700593 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700594 state = IccCardConstants.State.ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -0700595 }
Wink Savillea639b312012-07-10 12:37:54 -0700596 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
597 state = IccCardConstants.State.READY;
598 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800599 final String lockedReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700600 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
601 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
602 state = IccCardConstants.State.PIN_REQUIRED;
603 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
604 state = IccCardConstants.State.PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800605 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700606 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800607 }
Wink Savillea639b312012-07-10 12:37:54 -0700608 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
609 state = IccCardConstants.State.NETWORK_LOCKED;
Jim Miller109f1fd2012-09-19 20:44:16 -0700610 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
611 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
612 // This is required because telephony doesn't return to "READY" after
613 // these state transitions. See bug 7197471.
614 state = IccCardConstants.State.READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800615 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700616 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800617 }
Jim Miller52a61332014-11-12 19:29:51 -0800618 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800619 }
620
621 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -0800622 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800623 }
624 }
625
Adrian Roos12c1ef52014-06-04 13:54:08 +0200626 public static class BatteryStatus {
Jim Miller16464b82011-10-20 21:10:13 -0700627 public final int status;
628 public final int level;
629 public final int plugged;
630 public final int health;
631 public BatteryStatus(int status, int level, int plugged, int health) {
632 this.status = status;
633 this.level = level;
634 this.plugged = plugged;
635 this.health = health;
636 }
637
Jim Millerbbf1a742012-07-17 18:30:30 -0700638 /**
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700639 * Determine whether the device is plugged in (USB, power, or wireless).
Jim Millerbbf1a742012-07-17 18:30:30 -0700640 * @return true if the device is plugged in.
641 */
Adrian Roosad3bc7f2014-10-30 18:29:38 +0100642 public boolean isPluggedIn() {
Jim Millerbbf1a742012-07-17 18:30:30 -0700643 return plugged == BatteryManager.BATTERY_PLUGGED_AC
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700644 || plugged == BatteryManager.BATTERY_PLUGGED_USB
645 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Jim Millerbbf1a742012-07-17 18:30:30 -0700646 }
647
648 /**
649 * Whether or not the device is charged. Note that some devices never return 100% for
650 * battery level, so this allows either battery level or status to determine if the
651 * battery is charged.
652 * @return true if the device is charged
653 */
654 public boolean isCharged() {
655 return status == BATTERY_STATUS_FULL || level >= 100;
656 }
657
658 /**
659 * Whether battery is low and needs to be charged.
660 * @return true if battery is low
661 */
662 public boolean isBatteryLow() {
663 return level < LOW_BATTERY_THRESHOLD;
664 }
665
Jim Miller16464b82011-10-20 21:10:13 -0700666 }
667
Jim Millerdcb3d842012-08-23 19:18:12 -0700668 public static KeyguardUpdateMonitor getInstance(Context context) {
669 if (sInstance == null) {
670 sInstance = new KeyguardUpdateMonitor(context);
671 }
672 return sInstance;
673 }
674
Jim Miller20daffd2013-10-07 14:59:53 -0700675 protected void handleScreenTurnedOn() {
676 final int count = mCallbacks.size();
677 for (int i = 0; i < count; i++) {
678 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
679 if (cb != null) {
680 cb.onScreenTurnedOn();
681 }
682 }
Jorim Jaggiea657062015-04-28 13:45:11 -0700683 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -0700684 }
685
686 protected void handleScreenTurnedOff(int arg1) {
Jim Millerf41fc962014-06-18 16:33:51 -0700687 clearFingerprintRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -0700688 final int count = mCallbacks.size();
689 for (int i = 0; i < count; i++) {
690 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
691 if (cb != null) {
692 cb.onScreenTurnedOff(arg1);
693 }
694 }
Jorim Jaggiea657062015-04-28 13:45:11 -0700695 updateFingerprintListeningState();
Jim Miller20daffd2013-10-07 14:59:53 -0700696 }
697
Adam Powell43a372f2013-09-27 17:43:53 -0700698 /**
699 * IMPORTANT: Must be called from UI thread.
700 */
701 public void dispatchSetBackground(Bitmap bmp) {
702 if (DEBUG) Log.d(TAG, "dispatchSetBackground");
703 final int count = mCallbacks.size();
704 for (int i = 0; i < count; i++) {
705 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
706 if (cb != null) {
707 cb.onSetBackground(bmp);
708 }
709 }
710 }
711
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700712 private void handleUserInfoChanged(int userId) {
713 for (int i = 0; i < mCallbacks.size(); i++) {
714 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
715 if (cb != null) {
716 cb.onUserInfoChanged(userId);
717 }
718 }
719 }
720
Jim Millerdcb3d842012-08-23 19:18:12 -0700721 private KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800722 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800723 mSubscriptionManager = SubscriptionManager.from(context);
Michael Jurkafff56142012-11-28 16:51:00 -0800724 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800725 // Since device can't be un-provisioned, we only need to register a content observer
726 // to update mDeviceProvisioned when we are...
727 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700728 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800729 }
Jim Miller47088bb2009-11-24 00:40:16 -0800730
Jim Millerbbf1a742012-07-17 18:30:30 -0700731 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Jim Miller16464b82011-10-20 21:10:13 -0700732 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800733
Jim Millerbbf1a742012-07-17 18:30:30 -0700734 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800735 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800736 filter.addAction(Intent.ACTION_TIME_TICK);
737 filter.addAction(Intent.ACTION_TIME_CHANGED);
738 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
739 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
740 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -0800741 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -0800742 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Jim Millerbbf1a742012-07-17 18:30:30 -0700743 context.registerReceiver(mBroadcastReceiver, filter);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700744
Adam Cohenc276e822012-11-08 13:01:08 -0800745 final IntentFilter bootCompleteFilter = new IntentFilter();
746 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
747 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
748 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter);
749
Adrian Roos48c796c2014-09-01 14:59:23 +0200750 final IntentFilter allUserFilter = new IntentFilter();
751 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
752 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
753 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
754 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
755 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
756 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700757 null, null);
758
Wink Saville071743f2015-01-12 17:11:04 -0800759 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700760 try {
761 ActivityManagerNative.getDefault().registerUserSwitchObserver(
762 new IUserSwitchObserver.Stub() {
763 @Override
764 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -0500765 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700766 newUserId, 0, reply));
Brian Colonnaa5239892013-04-15 11:45:40 -0400767 mSwitchingUser = true;
Jorim Jaggiea657062015-04-28 13:45:11 -0700768 updateFingerprintListeningState();
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700769 }
770 @Override
771 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -0500772 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +0200773 newUserId, 0));
Brian Colonnaa5239892013-04-15 11:45:40 -0400774 mSwitchingUser = false;
Jorim Jaggiea657062015-04-28 13:45:11 -0700775 updateFingerprintListeningState();
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700776 }
Kenny Guy42979622015-04-13 18:03:05 +0000777 @Override
778 public void onForegroundProfileSwitch(int newProfileId) {
779 // Ignore.
780 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700781 });
782 } catch (RemoteException e) {
783 // TODO Auto-generated catch block
784 e.printStackTrace();
785 }
Adrian Roos46842d92014-03-27 14:58:03 +0100786
Jorim Jaggi237b0612015-05-01 14:28:49 -0700787 mTrustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
788 mTrustManager.registerTrustListener(this);
Jim Millerf41fc962014-06-18 16:33:51 -0700789
Jim Miller9f0753f2015-03-23 23:59:22 -0700790 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
Jorim Jaggiea657062015-04-28 13:45:11 -0700791 updateFingerprintListeningState();
792 }
793
794 private void updateFingerprintListeningState() {
795 boolean shouldListenForFingerprint = shouldListenForFingerprint();
796 if (mFingerprintDetectionRunning && !shouldListenForFingerprint) {
797 stopListeningForFingerprint();
798 } else if (!mFingerprintDetectionRunning && shouldListenForFingerprint) {
799 startListeningForFingerprint();
800 }
801 }
802
803 private boolean shouldListenForFingerprint() {
Jorim Jaggi237b0612015-05-01 14:28:49 -0700804 return mScreenOn && mKeyguardIsVisible && !mSwitchingUser
805 && mTrustManager.hasUserAuthenticatedSinceBoot(ActivityManager.getCurrentUser());
Jim Miller9f0753f2015-03-23 23:59:22 -0700806 }
807
Jim Millerce7eb6d2015-04-03 19:29:13 -0700808 private void startListeningForFingerprint() {
809 if (DEBUG) Log.v(TAG, "startListeningForFingerprint()");
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -0700810 int userId = ActivityManager.getCurrentUser();
Jim Millerce7eb6d2015-04-03 19:29:13 -0700811 if (mFpm != null && mFpm.isHardwareDetected() && !isFingerprintDisabled(userId)
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -0700812 && mFpm.getEnrolledFingerprints(userId).size() > 0) {
Jim Millerce7eb6d2015-04-03 19:29:13 -0700813 if (mFingerprintCancelSignal != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700814 mFingerprintCancelSignal.cancel();
815 }
Jim Millerce7eb6d2015-04-03 19:29:13 -0700816 mFingerprintCancelSignal = new CancellationSignal();
Jorim Jaggi2aad7ee2015-04-14 15:25:06 -0700817 mFpm.authenticate(null, mFingerprintCancelSignal, mAuthenticationCallback, 0, userId);
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700818 setFingerprintRunningDetectionRunning(true);
Jim Miller9f0753f2015-03-23 23:59:22 -0700819 }
820 }
821
Jorim Jaggiea657062015-04-28 13:45:11 -0700822 private void stopListeningForFingerprint() {
Jim Millerce7eb6d2015-04-03 19:29:13 -0700823 if (DEBUG) Log.v(TAG, "stopListeningForFingerprint()");
824 if (isFingerprintDetectionRunning()) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700825 mFingerprintCancelSignal.cancel();
Jim Millerce7eb6d2015-04-03 19:29:13 -0700826 mFingerprintCancelSignal = null;
Jim Miller9f0753f2015-03-23 23:59:22 -0700827 }
Jorim Jaggi27c9b742015-04-09 10:34:49 -0700828 setFingerprintRunningDetectionRunning(false);
Jim Millerbbf1a742012-07-17 18:30:30 -0700829 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800830
Michael Jurkafff56142012-11-28 16:51:00 -0800831 private boolean isDeviceProvisionedInSettingsDb() {
832 return Settings.Global.getInt(mContext.getContentResolver(),
833 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
834 }
835
Jim Millerbbf1a742012-07-17 18:30:30 -0700836 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -0800837 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700838 @Override
839 public void onChange(boolean selfChange) {
840 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -0800841 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -0700842 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -0700843 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800844 }
Jim Millerbbf1a742012-07-17 18:30:30 -0700845 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800846 }
Jim Millerbbf1a742012-07-17 18:30:30 -0700847 };
848
849 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -0700850 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -0800851 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -0700852
853 // prevent a race condition between where we check the flag and where we register the
854 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -0800855 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -0700856 if (provisioned != mDeviceProvisioned) {
857 mDeviceProvisioned = provisioned;
858 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -0700859 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -0700860 }
861 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800862 }
863
Jim Millerbbf1a742012-07-17 18:30:30 -0700864 /**
865 * Handle {@link #MSG_DPM_STATE_CHANGED}
866 */
Jim Millerb0304762012-03-13 20:01:25 -0700867 protected void handleDevicePolicyManagerStateChanged() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700868 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
869 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
870 if (cb != null) {
871 cb.onDevicePolicyManagerStateChanged();
872 }
Jim Millerb0304762012-03-13 20:01:25 -0700873 }
874 }
875
Jim Millerbbf1a742012-07-17 18:30:30 -0700876 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -0500877 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -0700878 */
Chris Wrenf41c61b2012-11-29 15:19:54 -0500879 protected void handleUserSwitching(int userId, IRemoteCallback reply) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700880 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700881 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
882 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -0500883 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -0700884 }
Amith Yamasani52c489c2012-03-28 11:42:42 -0700885 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700886 try {
887 reply.sendResult(null);
888 } catch (RemoteException e) {
889 }
Amith Yamasani52c489c2012-03-28 11:42:42 -0700890 }
891
Jim Millerbbf1a742012-07-17 18:30:30 -0700892 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -0500893 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
894 */
895 protected void handleUserSwitchComplete(int userId) {
896 for (int i = 0; i < mCallbacks.size(); i++) {
897 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
898 if (cb != null) {
899 cb.onUserSwitchComplete(userId);
900 }
901 }
902 }
903
904 /**
Jim Miller90873d52013-09-26 18:11:38 -0700905 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
906 * keyguard crashes sometime after boot, then it will never receive this
907 * broadcast and hence not handle the event. This method is ultimately called by
908 * PhoneWindowManager in this case.
909 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100910 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -0700911 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -0700912 }
913
914 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800915 * Handle {@link #MSG_BOOT_COMPLETED}
916 */
917 protected void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -0700918 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800919 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800920 for (int i = 0; i < mCallbacks.size(); i++) {
921 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
922 if (cb != null) {
923 cb.onBootCompleted();
924 }
925 }
926 }
927
928 /**
Jim Miller5ecd8112013-01-09 18:50:26 -0800929 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800930 * destroyed.
931 */
932 public boolean hasBootCompleted() {
933 return mBootCompleted;
934 }
935
936 /**
Jim Millerbbf1a742012-07-17 18:30:30 -0700937 * Handle {@link #MSG_DEVICE_PROVISIONED}
938 */
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700939 protected void handleDeviceProvisioned() {
Jim Millerbbf1a742012-07-17 18:30:30 -0700940 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700941 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
942 if (cb != null) {
943 cb.onDeviceProvisioned();
944 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700945 }
Michael Jurkafff56142012-11-28 16:51:00 -0800946 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700947 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -0800948 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
949 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700950 }
951 }
952
Jim Millerbbf1a742012-07-17 18:30:30 -0700953 /**
954 * Handle {@link #MSG_PHONE_STATE_CHANGED}
955 */
Jim Millerc23024d2010-02-24 15:37:00 -0800956 protected void handlePhoneStateChanged(String newState) {
957 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -0700958 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
959 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
960 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
961 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
962 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
963 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
964 }
Jim Millerbbf1a742012-07-17 18:30:30 -0700965 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700966 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
967 if (cb != null) {
968 cb.onPhoneStateChanged(mPhoneState);
969 }
Jim Millerc23024d2010-02-24 15:37:00 -0800970 }
971 }
972
Jim Millerbbf1a742012-07-17 18:30:30 -0700973 /**
974 * Handle {@link #MSG_RINGER_MODE_CHANGED}
975 */
Jim Miller47088bb2009-11-24 00:40:16 -0800976 protected void handleRingerModeChange(int mode) {
977 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -0700978 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -0700979 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700980 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
981 if (cb != null) {
982 cb.onRingerModeChanged(mode);
983 }
Jim Miller47088bb2009-11-24 00:40:16 -0800984 }
985 }
986
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800987 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800988 * Handle {@link #MSG_TIME_UPDATE}
989 */
990 private void handleTimeUpdate() {
991 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -0700992 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700993 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
994 if (cb != null) {
995 cb.onTimeChanged();
996 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800997 }
998 }
999
1000 /**
1001 * Handle {@link #MSG_BATTERY_UPDATE}
1002 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001003 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001004 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -07001005 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
1006 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -07001007 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001008 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001009 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1010 if (cb != null) {
1011 cb.onRefreshBatteryInfo(status);
1012 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001013 }
1014 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001015 }
1016
1017 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001018 * Handle {@link #MSG_SIM_STATE_CHANGE}
1019 */
Jim Miller52a61332014-11-12 19:29:51 -08001020 private void handleSimStateChange(int subId, int slotId, State state) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001021
Jim Miller52a61332014-11-12 19:29:51 -08001022 if (DEBUG_SIM_STATES) {
1023 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
1024 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001025 }
1026
Wink Savillea54bf652014-12-11 13:37:50 -08001027 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -08001028 Log.w(TAG, "invalid subId in handleSimStateChange()");
1029 return;
1030 }
1031
1032 SimData data = mSimDatas.get(subId);
1033 final boolean changed;
1034 if (data == null) {
1035 data = new SimData(state, slotId, subId);
1036 mSimDatas.put(subId, data);
1037 changed = true; // no data yet; force update
1038 } else {
1039 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
1040 data.simState = state;
1041 data.subId = subId;
1042 data.slotId = slotId;
1043 }
1044 if (changed && state != State.UNKNOWN) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001045 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001046 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1047 if (cb != null) {
Jim Miller52a61332014-11-12 19:29:51 -08001048 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -07001049 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001050 }
1051 }
1052 }
1053
Jim Millerbbf1a742012-07-17 18:30:30 -07001054 /**
1055 * Handle {@link #MSG_CLOCK_VISIBILITY_CHANGED}
1056 */
Jeff Sharkey054340d2011-09-01 22:28:03 -07001057 private void handleClockVisibilityChanged() {
1058 if (DEBUG) Log.d(TAG, "handleClockVisibilityChanged()");
Jim Millerbbf1a742012-07-17 18:30:30 -07001059 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -07001060 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1061 if (cb != null) {
1062 cb.onClockVisibilityChanged();
1063 }
Jeff Sharkey054340d2011-09-01 22:28:03 -07001064 }
1065 }
1066
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001067 /**
1068 * Handle {@link #MSG_KEYGUARD_VISIBILITY_CHANGED}
1069 */
1070 private void handleKeyguardVisibilityChanged(int showing) {
1071 if (DEBUG) Log.d(TAG, "handleKeyguardVisibilityChanged(" + showing + ")");
Danielle Millett5d2404d2012-11-01 00:05:27 -04001072 boolean isShowing = (showing == 1);
1073 mKeyguardIsVisible = isShowing;
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001074 for (int i = 0; i < mCallbacks.size(); i++) {
1075 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1076 if (cb != null) {
John Spurlock385a63d2013-10-30 19:40:48 -04001077 cb.onKeyguardVisibilityChangedRaw(isShowing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001078 }
1079 }
Jorim Jaggiea657062015-04-28 13:45:11 -07001080 updateFingerprintListeningState();
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001081 }
1082
Brian Colonna7fce3802013-09-17 15:51:32 -04001083 /**
Adrian Roosb6011622014-05-14 15:52:53 +02001084 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
1085 * @see #sendKeyguardBouncerChanged(boolean)
1086 */
1087 private void handleKeyguardBouncerChanged(int bouncer) {
1088 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
1089 boolean isBouncer = (bouncer == 1);
1090 mBouncer = isBouncer;
1091 for (int i = 0; i < mCallbacks.size(); i++) {
1092 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1093 if (cb != null) {
1094 cb.onKeyguardBouncerChanged(isBouncer);
1095 }
1096 }
1097 }
1098
1099 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04001100 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
1101 */
1102 private void handleReportEmergencyCallAction() {
1103 for (int i = 0; i < mCallbacks.size(); i++) {
1104 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1105 if (cb != null) {
1106 cb.onEmergencyCallAction();
1107 }
1108 }
1109 }
1110
Danielle Millett5d2404d2012-11-01 00:05:27 -04001111 public boolean isKeyguardVisible() {
1112 return mKeyguardIsVisible;
1113 }
1114
Adrian Roosb6011622014-05-14 15:52:53 +02001115 /**
1116 * @return if the keyguard is currently in bouncer mode.
1117 */
1118 public boolean isKeyguardBouncer() {
1119 return mBouncer;
1120 }
1121
Brian Colonnaa5239892013-04-15 11:45:40 -04001122 public boolean isSwitchingUser() {
1123 return mSwitchingUser;
1124 }
1125
Jim Miller16464b82011-10-20 21:10:13 -07001126 private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001127 final boolean nowPluggedIn = current.isPluggedIn();
1128 final boolean wasPluggedIn = old.isPluggedIn();
Jim Miller79a444a2011-02-15 15:02:11 -08001129 final boolean stateChangedWhilePluggedIn =
Jim Miller16464b82011-10-20 21:10:13 -07001130 wasPluggedIn == true && nowPluggedIn == true
1131 && (old.status != current.status);
1132
1133 // change in plug state is always interesting
1134 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001135 return true;
1136 }
1137
1138 // change in battery level while plugged in
Jim Miller16464b82011-10-20 21:10:13 -07001139 if (nowPluggedIn && old.level != current.level) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001140 return true;
1141 }
1142
Jim Miller16464b82011-10-20 21:10:13 -07001143 // change where battery needs charging
Jim Millerbbf1a742012-07-17 18:30:30 -07001144 if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
Jim Miller16464b82011-10-20 21:10:13 -07001145 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001146 }
1147 return false;
1148 }
1149
1150 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001151 * @return The default plmn (no service)
1152 */
1153 private CharSequence getDefaultPlmn() {
Jim Miller5ecd8112013-01-09 18:50:26 -08001154 return mContext.getResources().getText(R.string.keyguard_carrier_default);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001155 }
1156
1157 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001158 * Remove the given observer's callback.
1159 *
Jim Miller6212cc02012-09-05 17:35:31 -07001160 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001161 */
Jim Miller6212cc02012-09-05 17:35:31 -07001162 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
1163 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
1164 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1165 if (mCallbacks.get(i).get() == callback) {
1166 mCallbacks.remove(i);
1167 }
1168 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001169 }
1170
1171 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001172 * Register to receive notifications about general keyguard information
1173 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07001174 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001175 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001176 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Jim Miller6212cc02012-09-05 17:35:31 -07001177 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
1178 // Prevent adding duplicate callbacks
1179 for (int i = 0; i < mCallbacks.size(); i++) {
1180 if (mCallbacks.get(i).get() == callback) {
1181 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
1182 new Exception("Called by"));
1183 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07001184 }
1185 }
Jim Miller6212cc02012-09-05 17:35:31 -07001186 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
1187 removeCallback(null); // remove unused references
1188 sendUpdates(callback);
1189 }
1190
1191 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
1192 // Notify listener of the current state
1193 callback.onRefreshBatteryInfo(mBatteryStatus);
1194 callback.onTimeChanged();
1195 callback.onRingerModeChanged(mRingMode);
1196 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05001197 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07001198 callback.onClockVisibilityChanged();
Jim Miller52a61332014-11-12 19:29:51 -08001199 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
1200 final SimData state = data.getValue();
1201 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
1202 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001203 }
1204
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001205 public void sendKeyguardVisibilityChanged(boolean showing) {
1206 if (DEBUG) Log.d(TAG, "sendKeyguardVisibilityChanged(" + showing + ")");
1207 Message message = mHandler.obtainMessage(MSG_KEYGUARD_VISIBILITY_CHANGED);
1208 message.arg1 = showing ? 1 : 0;
1209 message.sendToTarget();
1210 }
1211
Adrian Roosb6011622014-05-14 15:52:53 +02001212 /**
1213 * @see #handleKeyguardBouncerChanged(int)
1214 */
1215 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
1216 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
1217 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
1218 message.arg1 = showingBouncer ? 1 : 0;
1219 message.sendToTarget();
1220 }
1221
Jeff Sharkey054340d2011-09-01 22:28:03 -07001222 public void reportClockVisible(boolean visible) {
1223 mClockVisible = visible;
1224 mHandler.obtainMessage(MSG_CLOCK_VISIBILITY_CHANGED).sendToTarget();
1225 }
1226
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001227 /**
Jim Miller90d5d462011-11-17 16:57:01 -08001228 * 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 -08001229 * have the information earlier than waiting for the intent
1230 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08001231 *
1232 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
1233 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001234 */
Jim Miller52a61332014-11-12 19:29:51 -08001235 public void reportSimUnlocked(int subId) {
1236 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
1237 int slotId = SubscriptionManager.getSlotId(subId);
1238 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001239 }
1240
Brian Colonna7fce3802013-09-17 15:51:32 -04001241 /**
1242 * Report that the emergency call button has been pressed and the emergency dialer is
1243 * about to be displayed.
1244 *
1245 * @param bypassHandler runs immediately.
1246 *
1247 * NOTE: Must be called from UI thread if bypassHandler == true.
1248 */
1249 public void reportEmergencyCallAction(boolean bypassHandler) {
1250 if (!bypassHandler) {
1251 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
1252 } else {
1253 handleReportEmergencyCallAction();
1254 }
1255 }
1256
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001257 /**
1258 * @return Whether the device is provisioned (whether they have gone through
1259 * the setup wizard)
1260 */
1261 public boolean isDeviceProvisioned() {
1262 return mDeviceProvisioned;
1263 }
1264
Jorim Jaggi9f743032015-05-04 15:22:40 -07001265 public void clearFailedUnlockAttempts() {
1266 mFailedAttempts.delete(sCurrentUser);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001267 }
1268
Jorim Jaggi9f743032015-05-04 15:22:40 -07001269 public int getFailedUnlockAttempts() {
1270 return mFailedAttempts.get(sCurrentUser, 0);
1271 }
1272
1273 public void reportFailedUnlockAttempt() {
1274 mFailedAttempts.put(sCurrentUser, getFailedUnlockAttempts() + 1);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001275 }
1276
Jim Millerf41fc962014-06-18 16:33:51 -07001277 public void clearFingerprintRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07001278 mUserFingerprintAuthenticated.clear();
Jim Millerf41fc962014-06-18 16:33:51 -07001279 }
1280
Jim Miller52a61332014-11-12 19:29:51 -08001281 public boolean isSimPinVoiceSecure() {
1282 // TODO: only count SIMs that handle voice
1283 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07001284 }
1285
1286 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08001287 // True if any SIM is pin secure
1288 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
1289 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
1290 }
1291 return false;
1292 }
1293
Jason Monk9ff69bd2014-12-02 16:43:17 -05001294 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08001295 if (mSimDatas.containsKey(subId)) {
1296 return mSimDatas.get(subId).simState;
1297 } else {
1298 return State.UNKNOWN;
1299 }
1300 }
1301
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001302 /**
1303 * @return true if and only if the state has changed for the specified {@code slotId}
1304 */
1305 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08001306
1307 // This is awful. It exists because there are two APIs for getting the SIM status
1308 // that don't return the complete set of values and have different types. In Keyguard we
1309 // need IccCardConstants, but TelephonyManager would only give us
1310 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08001311 final TelephonyManager tele = TelephonyManager.from(mContext);
1312 int simState = tele.getSimState(slotId);
Jim Miller52a61332014-11-12 19:29:51 -08001313 State state;
1314 try {
xinhe18b9c3c2014-12-02 15:03:20 -08001315 state = State.intToState(simState);
Jim Miller52a61332014-11-12 19:29:51 -08001316 } catch(IllegalArgumentException ex) {
xinhe18b9c3c2014-12-02 15:03:20 -08001317 Log.w(TAG, "Unknown sim state: " + simState);
Jim Miller52a61332014-11-12 19:29:51 -08001318 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05001319 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001320 SimData data = mSimDatas.get(subId);
1321 final boolean changed;
1322 if (data == null) {
1323 data = new SimData(state, slotId, subId);
1324 mSimDatas.put(subId, data);
1325 changed = true; // no data yet; force update
1326 } else {
1327 changed = data.simState != state;
1328 data.simState = state;
1329 }
1330 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07001331 }
1332
1333 public static boolean isSimPinSecure(IccCardConstants.State state) {
1334 final IccCardConstants.State simState = state;
1335 return (simState == IccCardConstants.State.PIN_REQUIRED
1336 || simState == IccCardConstants.State.PUK_REQUIRED
1337 || simState == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07001338 }
Jim Miller8f09fd22013-03-14 19:04:28 -07001339
1340 public DisplayClientState getCachedDisplayClientState() {
1341 return mDisplayClientState;
1342 }
Jim Miller20daffd2013-10-07 14:59:53 -07001343
1344 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
1345 // (KeyguardViewMediator, KeyguardHostView)
1346 public void dispatchScreenTurnedOn() {
1347 synchronized (this) {
1348 mScreenOn = true;
1349 }
1350 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
1351 }
1352
John Spurlock36a13422015-03-24 21:15:48 -04001353 public void dispatchScreenTurnedOff(int why) {
Jim Miller20daffd2013-10-07 14:59:53 -07001354 synchronized(this) {
1355 mScreenOn = false;
1356 }
1357 mHandler.sendMessage(mHandler.obtainMessage(MSG_SCREEN_TURNED_OFF, why, 0));
1358 }
1359
1360 public boolean isScreenOn() {
1361 return mScreenOn;
1362 }
Jim Miller52a61332014-11-12 19:29:51 -08001363
1364 /**
1365 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
1366 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08001367 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08001368 */
1369 public int getNextSubIdForState(State state) {
1370 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08001371 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08001372 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
1373 for (int i = 0; i < list.size(); i++) {
1374 final SubscriptionInfo info = list.get(i);
1375 final int id = info.getSubscriptionId();
1376 int slotId = SubscriptionManager.getSlotId(id);
1377 if (state == getSimState(id) && bestSlotId > slotId ) {
1378 resultId = id;
1379 bestSlotId = slotId;
1380 }
1381 }
1382 return resultId;
1383 }
1384
1385 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
1386 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
1387 for (int i = 0; i < list.size(); i++) {
1388 SubscriptionInfo info = list.get(i);
1389 if (subId == info.getSubscriptionId()) return info;
1390 }
1391 return null; // not found
1392 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001393}