blob: a92821149401cdb17876b5bd95ea086201531da9 [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
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070019import android.app.ActivityManagerNative;
Jorim Jaggic7dea6e2014-07-26 14:36:57 +020020import android.app.AlarmManager;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070021import android.app.IUserSwitchObserver;
Jim Miller8f09fd22013-03-14 19:04:28 -070022import android.app.PendingIntent;
Jim Millerb0304762012-03-13 20:01:25 -070023import android.app.admin.DevicePolicyManager;
Adrian Roos46842d92014-03-27 14:58:03 +010024import android.app.trust.TrustManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080025import android.content.BroadcastReceiver;
Jim Millerf41fc962014-06-18 16:33:51 -070026import android.content.ContentResolver;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080027import android.content.Context;
28import android.content.Intent;
29import android.content.IntentFilter;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080030import android.database.ContentObserver;
Jim Miller8f09fd22013-03-14 19:04:28 -070031import android.graphics.Bitmap;
32
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080033import static android.os.BatteryManager.BATTERY_STATUS_FULL;
34import static android.os.BatteryManager.BATTERY_STATUS_UNKNOWN;
Jim Miller16464b82011-10-20 21:10:13 -070035import static android.os.BatteryManager.BATTERY_HEALTH_UNKNOWN;
36import static android.os.BatteryManager.EXTRA_STATUS;
37import static android.os.BatteryManager.EXTRA_PLUGGED;
38import static android.os.BatteryManager.EXTRA_LEVEL;
39import static android.os.BatteryManager.EXTRA_HEALTH;
Jim Miller06e34502014-07-17 14:46:05 -070040
Jim Miller47088bb2009-11-24 00:40:16 -080041import android.media.AudioManager;
Jim Miller79a444a2011-02-15 15:02:11 -080042import android.os.BatteryManager;
Jim Miller9f0753f2015-03-23 23:59:22 -070043import android.os.CancellationSignal;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080044import android.os.Handler;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070045import android.os.IRemoteCallback;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080046import android.os.Message;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -070047import android.os.RemoteException;
Amith Yamasanie8e93a12013-05-09 18:12:30 -070048import android.os.UserHandle;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080049import android.provider.Settings;
Dianne Hackbornb7e787f2009-05-07 15:55:42 -070050
Wink Savillea639b312012-07-10 12:37:54 -070051import com.android.internal.telephony.IccCardConstants;
Jim Miller52a61332014-11-12 19:29:51 -080052import com.android.internal.telephony.IccCardConstants.State;
53import com.android.internal.telephony.PhoneConstants;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080054import com.android.internal.telephony.TelephonyIntents;
Jim Miller9f0753f2015-03-23 23:59:22 -070055
Jim Millerebbf2052015-03-31 17:24:34 -070056import android.hardware.fingerprint.FingerprintManager;
57import android.hardware.fingerprint.FingerprintManager.AuthenticationCallback;
58import android.hardware.fingerprint.FingerprintUtils;
59import android.hardware.fingerprint.FingerprintManager.AuthenticationResult;
Jim Miller52a61332014-11-12 19:29:51 -080060import android.telephony.SubscriptionInfo;
Jim Miller52a61332014-11-12 19:29:51 -080061import android.telephony.SubscriptionManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -080062import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Jim Millerc23024d2010-02-24 15:37:00 -080063import android.telephony.TelephonyManager;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080064import android.util.Log;
Adrian Roos46842d92014-03-27 14:58:03 +010065import android.util.SparseBooleanArray;
66
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080067import com.google.android.collect.Lists;
68
Jim Millerdcb3d842012-08-23 19:18:12 -070069import java.lang.ref.WeakReference;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080070import java.util.ArrayList;
Jim Miller52a61332014-11-12 19:29:51 -080071import java.util.HashMap;
72import java.util.List;
73import java.util.Map.Entry;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080074
75/**
76 * Watches for updates that may be interesting to the keyguard, and provides
77 * the up to date information as well as a registration for callbacks that care
78 * to be updated.
79 *
80 * Note: under time crunch, this has been extended to include some stuff that
81 * doesn't really belong here. see {@link #handleBatteryUpdate} where it shutdowns
Jim Miller258341c2012-08-30 16:50:10 -070082 * the device, and {@link #getFailedUnlockAttempts()}, {@link #reportFailedAttempt()}
83 * and {@link #clearFailedUnlockAttempts()}. Maybe we should rename this 'KeyguardContext'...
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080084 */
Adrian Roos46842d92014-03-27 14:58:03 +010085public class KeyguardUpdateMonitor implements TrustManager.TrustListener {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080086
Jim Millerbbf1a742012-07-17 18:30:30 -070087 private static final String TAG = "KeyguardUpdateMonitor";
Jorim Jaggi5cf17872014-03-26 18:31:48 +010088 private static final boolean DEBUG = KeyguardConstants.DEBUG;
Jim Miller52a61332014-11-12 19:29:51 -080089 private static final boolean DEBUG_SIM_STATES = KeyguardConstants.DEBUG_SIM_STATES;
Jim Millerbbf1a742012-07-17 18:30:30 -070090 private static final int LOW_BATTERY_THRESHOLD = 20;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080091
Jorim Jaggie7b12522014-08-06 16:41:21 +020092 private static final String ACTION_FACE_UNLOCK_STARTED
93 = "com.android.facelock.FACE_UNLOCK_STARTED";
94 private static final String ACTION_FACE_UNLOCK_STOPPED
95 = "com.android.facelock.FACE_UNLOCK_STOPPED";
96
Jim Millerbbf1a742012-07-17 18:30:30 -070097 // Callback messages
The Android Open Source Project1f838aa2009-03-03 19:32:13 -080098 private static final int MSG_TIME_UPDATE = 301;
99 private static final int MSG_BATTERY_UPDATE = 302;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800100 private static final int MSG_SIM_STATE_CHANGE = 304;
Jim Miller47088bb2009-11-24 00:40:16 -0800101 private static final int MSG_RINGER_MODE_CHANGED = 305;
Jim Millerc23024d2010-02-24 15:37:00 -0800102 private static final int MSG_PHONE_STATE_CHANGED = 306;
Jeff Sharkey054340d2011-09-01 22:28:03 -0700103 private static final int MSG_CLOCK_VISIBILITY_CHANGED = 307;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700104 private static final int MSG_DEVICE_PROVISIONED = 308;
Jim Miller57375342012-09-09 15:20:31 -0700105 private static final int MSG_DPM_STATE_CHANGED = 309;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500106 private static final int MSG_USER_SWITCHING = 310;
Danielle Millettf6d0fc12012-10-23 16:16:52 -0400107 private static final int MSG_KEYGUARD_VISIBILITY_CHANGED = 312;
Jim Millerf41fc962014-06-18 16:33:51 -0700108 private static final int MSG_BOOT_COMPLETED = 313;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500109 private static final int MSG_USER_SWITCH_COMPLETE = 314;
Jim Millerf41fc962014-06-18 16:33:51 -0700110 private static final int MSG_USER_INFO_CHANGED = 317;
111 private static final int MSG_REPORT_EMERGENCY_CALL_ACTION = 318;
Jim Miller20daffd2013-10-07 14:59:53 -0700112 private static final int MSG_SCREEN_TURNED_ON = 319;
113 private static final int MSG_SCREEN_TURNED_OFF = 320;
Adrian Roosb6011622014-05-14 15:52:53 +0200114 private static final int MSG_KEYGUARD_BOUNCER_CHANGED = 322;
Jim Miller9f0753f2015-03-23 23:59:22 -0700115 private static final int MSG_FINGERPRINT_AUTHENTICATED = 323;
116 private static final int MSG_FINGERPRINT_ERROR = 324;
117 private static final int MSG_FINGERPRINT_HELP = 325;
118 private static final int MSG_FACE_UNLOCK_STATE_CHANGED = 326;
119 private static final int MSG_SIM_SUBSCRIPTION_INFO_CHANGED = 327;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800120
Jim Millerdcb3d842012-08-23 19:18:12 -0700121 private static KeyguardUpdateMonitor sInstance;
122
Jim Millerbbf1a742012-07-17 18:30:30 -0700123 private final Context mContext;
Jim Miller52a61332014-11-12 19:29:51 -0800124 HashMap<Integer, SimData> mSimDatas = new HashMap<Integer, SimData>();
Jim Millerbbf1a742012-07-17 18:30:30 -0700125
Jim Millerbbf1a742012-07-17 18:30:30 -0700126 private int mRingMode;
127 private int mPhoneState;
Danielle Millett5d2404d2012-11-01 00:05:27 -0400128 private boolean mKeyguardIsVisible;
Adrian Roosb6011622014-05-14 15:52:53 +0200129 private boolean mBouncer;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800130 private boolean mBootCompleted;
Jim Millerbbf1a742012-07-17 18:30:30 -0700131
Jim Millerdcb3d842012-08-23 19:18:12 -0700132 // Device provisioning state
Jim Millerbbf1a742012-07-17 18:30:30 -0700133 private boolean mDeviceProvisioned;
134
Jim Millerdcb3d842012-08-23 19:18:12 -0700135 // Battery status
Jim Millerbbf1a742012-07-17 18:30:30 -0700136 private BatteryStatus mBatteryStatus;
137
Jim Millerdcb3d842012-08-23 19:18:12 -0700138 // Password attempts
Jim Millerbbf1a742012-07-17 18:30:30 -0700139 private int mFailedAttempts = 0;
Brian Colonnacc4104f2012-10-09 17:50:46 -0400140
Jim Millerbbf1a742012-07-17 18:30:30 -0700141 private boolean mClockVisible;
142
Jim Miller6212cc02012-09-05 17:35:31 -0700143 private final ArrayList<WeakReference<KeyguardUpdateMonitorCallback>>
Jim Millerdcb3d842012-08-23 19:18:12 -0700144 mCallbacks = Lists.newArrayList();
Michael Jurkafff56142012-11-28 16:51:00 -0800145 private ContentObserver mDeviceProvisionedObserver;
Jim Millerbbf1a742012-07-17 18:30:30 -0700146
Brian Colonnaa5239892013-04-15 11:45:40 -0400147 private boolean mSwitchingUser;
148
Jim Miller20daffd2013-10-07 14:59:53 -0700149 private boolean mScreenOn;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800150 private SubscriptionManager mSubscriptionManager;
151 private List<SubscriptionInfo> mSubscriptionInfo;
Jim Miller20daffd2013-10-07 14:59:53 -0700152
Jim Millerbbf1a742012-07-17 18:30:30 -0700153 private final Handler mHandler = new Handler() {
154 @Override
155 public void handleMessage(Message msg) {
156 switch (msg.what) {
157 case MSG_TIME_UPDATE:
158 handleTimeUpdate();
159 break;
160 case MSG_BATTERY_UPDATE:
161 handleBatteryUpdate((BatteryStatus) msg.obj);
162 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700163 case MSG_SIM_STATE_CHANGE:
Jim Miller52a61332014-11-12 19:29:51 -0800164 handleSimStateChange(msg.arg1, msg.arg2, (State) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700165 break;
166 case MSG_RINGER_MODE_CHANGED:
167 handleRingerModeChange(msg.arg1);
168 break;
169 case MSG_PHONE_STATE_CHANGED:
Adrian Roosb6011622014-05-14 15:52:53 +0200170 handlePhoneStateChanged((String) msg.obj);
Jim Millerbbf1a742012-07-17 18:30:30 -0700171 break;
172 case MSG_CLOCK_VISIBILITY_CHANGED:
173 handleClockVisibilityChanged();
174 break;
175 case MSG_DEVICE_PROVISIONED:
176 handleDeviceProvisioned();
177 break;
178 case MSG_DPM_STATE_CHANGED:
179 handleDevicePolicyManagerStateChanged();
180 break;
Chris Wrenf41c61b2012-11-29 15:19:54 -0500181 case MSG_USER_SWITCHING:
Adrian Roosb6011622014-05-14 15:52:53 +0200182 handleUserSwitching(msg.arg1, (IRemoteCallback) msg.obj);
Chris Wrenf41c61b2012-11-29 15:19:54 -0500183 break;
184 case MSG_USER_SWITCH_COMPLETE:
185 handleUserSwitchComplete(msg.arg1);
Jim Millerbbf1a742012-07-17 18:30:30 -0700186 break;
Danielle Millettf6d0fc12012-10-23 16:16:52 -0400187 case MSG_KEYGUARD_VISIBILITY_CHANGED:
188 handleKeyguardVisibilityChanged(msg.arg1);
189 break;
Adrian Roosb6011622014-05-14 15:52:53 +0200190 case MSG_KEYGUARD_BOUNCER_CHANGED:
191 handleKeyguardBouncerChanged(msg.arg1);
192 break;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800193 case MSG_BOOT_COMPLETED:
194 handleBootCompleted();
195 break;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700196 case MSG_USER_INFO_CHANGED:
197 handleUserInfoChanged(msg.arg1);
198 break;
Brian Colonna7fce3802013-09-17 15:51:32 -0400199 case MSG_REPORT_EMERGENCY_CALL_ACTION:
200 handleReportEmergencyCallAction();
201 break;
Jim Miller20daffd2013-10-07 14:59:53 -0700202 case MSG_SCREEN_TURNED_OFF:
203 handleScreenTurnedOff(msg.arg1);
204 break;
205 case MSG_SCREEN_TURNED_ON:
206 handleScreenTurnedOn();
207 break;
Jim Miller9f0753f2015-03-23 23:59:22 -0700208 case MSG_FINGERPRINT_AUTHENTICATED:
209 handleFingerprintAuthenticated(msg.arg1, msg.arg2);
Jim Millerf41fc962014-06-18 16:33:51 -0700210 break;
Jim Miller9f0753f2015-03-23 23:59:22 -0700211 case MSG_FINGERPRINT_HELP:
212 handleFingerprintHelp(msg.arg1 /* msgId */, (String) msg.obj /* errString */);
213 break;
214 case MSG_FINGERPRINT_ERROR:
215 handleFingerprintError(msg.arg1 /* msgId */, (String) msg.obj /* errString */);
Jim Millerf41fc962014-06-18 16:33:51 -0700216 break;
Jorim Jaggie7b12522014-08-06 16:41:21 +0200217 case MSG_FACE_UNLOCK_STATE_CHANGED:
Adrian Roos4a410172014-08-20 17:41:44 +0200218 handleFaceUnlockStateChanged(msg.arg1 != 0, msg.arg2);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200219 break;
Jim Miller52a61332014-11-12 19:29:51 -0800220 case MSG_SIM_SUBSCRIPTION_INFO_CHANGED:
221 handleSimSubscriptionInfoChanged();
222 break;
Jim Millerbbf1a742012-07-17 18:30:30 -0700223 }
224 }
225 };
226
Wink Savilled09c4ca2014-11-22 10:08:16 -0800227 private OnSubscriptionsChangedListener mSubscriptionListener =
228 new OnSubscriptionsChangedListener() {
Jim Miller52a61332014-11-12 19:29:51 -0800229 @Override
Wink Savilled09c4ca2014-11-22 10:08:16 -0800230 public void onSubscriptionsChanged() {
Jim Miller52a61332014-11-12 19:29:51 -0800231 mHandler.sendEmptyMessage(MSG_SIM_SUBSCRIPTION_INFO_CHANGED);
232 }
233 };
234
Adrian Roos46842d92014-03-27 14:58:03 +0100235 private SparseBooleanArray mUserHasTrust = new SparseBooleanArray();
Adrian Roos7861c662014-07-25 15:37:28 +0200236 private SparseBooleanArray mUserTrustIsManaged = new SparseBooleanArray();
Jim Miller9f0753f2015-03-23 23:59:22 -0700237 private SparseBooleanArray mUserFingerprintAuthenticated = new SparseBooleanArray();
Adrian Roos4a410172014-08-20 17:41:44 +0200238 private SparseBooleanArray mUserFaceUnlockRunning = new SparseBooleanArray();
Adrian Roos46842d92014-03-27 14:58:03 +0100239
240 @Override
Adrian Roos3c9a3502014-08-06 19:09:45 +0200241 public void onTrustChanged(boolean enabled, int userId, boolean initiatedByUser) {
Adrian Roos46842d92014-03-27 14:58:03 +0100242 mUserHasTrust.put(userId, enabled);
Adrian Roos2fe592d2014-05-17 03:11:59 +0200243
244 for (int i = 0; i < mCallbacks.size(); i++) {
245 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
246 if (cb != null) {
247 cb.onTrustChanged(userId);
Adrian Roos3c9a3502014-08-06 19:09:45 +0200248 if (enabled && initiatedByUser) {
249 cb.onTrustInitiatedByUser(userId);
250 }
Adrian Roos2fe592d2014-05-17 03:11:59 +0200251 }
252 }
Adrian Roos46842d92014-03-27 14:58:03 +0100253 }
254
Jim Miller52a61332014-11-12 19:29:51 -0800255 protected void handleSimSubscriptionInfoChanged() {
256 if (DEBUG_SIM_STATES) {
257 Log.v(TAG, "onSubscriptionInfoChanged()");
Wink Savilled09c4ca2014-11-22 10:08:16 -0800258 List<SubscriptionInfo> sil = mSubscriptionManager.getActiveSubscriptionInfoList();
259 if (sil != null) {
260 for (SubscriptionInfo subInfo : sil) {
261 Log.v(TAG, "SubInfo:" + subInfo);
262 }
263 } else {
264 Log.v(TAG, "onSubscriptionInfoChanged: list is null");
Jim Miller52a61332014-11-12 19:29:51 -0800265 }
266 }
267 List<SubscriptionInfo> subscriptionInfos = getSubscriptionInfo(true /* forceReload */);
268
269 // Hack level over 9000: Because the subscription id is not yet valid when we see the
270 // first update in handleSimStateChange, we need to force refresh all all SIM states
271 // so the subscription id for them is consistent.
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100272 ArrayList<SubscriptionInfo> changedSubscriptions = new ArrayList<>();
Jim Miller52a61332014-11-12 19:29:51 -0800273 for (int i = 0; i < subscriptionInfos.size(); i++) {
274 SubscriptionInfo info = subscriptionInfos.get(i);
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100275 boolean changed = refreshSimState(info.getSubscriptionId(), info.getSimSlotIndex());
276 if (changed) {
277 changedSubscriptions.add(info);
278 }
Jim Miller52a61332014-11-12 19:29:51 -0800279 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +0100280 for (int i = 0; i < changedSubscriptions.size(); i++) {
281 SimData data = mSimDatas.get(changedSubscriptions.get(i).getSubscriptionId());
Jim Miller52a61332014-11-12 19:29:51 -0800282 for (int j = 0; j < mCallbacks.size(); j++) {
283 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
284 if (cb != null) {
285 cb.onSimStateChanged(data.subId, data.slotId, data.simState);
286 }
287 }
288 }
Jason Monk6c985dc2015-01-09 16:07:14 -0500289 for (int j = 0; j < mCallbacks.size(); j++) {
290 KeyguardUpdateMonitorCallback cb = mCallbacks.get(j).get();
291 if (cb != null) {
292 cb.onRefreshCarrierInfo();
293 }
294 }
Jim Miller52a61332014-11-12 19:29:51 -0800295 }
296
Wink Savilled09c4ca2014-11-22 10:08:16 -0800297 /** @return List of SubscriptionInfo records, maybe empty but never null */
Jim Miller52a61332014-11-12 19:29:51 -0800298 List<SubscriptionInfo> getSubscriptionInfo(boolean forceReload) {
Wink Savilled09c4ca2014-11-22 10:08:16 -0800299 List<SubscriptionInfo> sil = mSubscriptionInfo;
300 if (sil == null || forceReload) {
301 sil = mSubscriptionManager.getActiveSubscriptionInfoList();
302 }
303 if (sil == null) {
304 // getActiveSubscriptionInfoList was null callers expect an empty list.
305 mSubscriptionInfo = new ArrayList<SubscriptionInfo>();
306 } else {
307 mSubscriptionInfo = sil;
Jim Miller52a61332014-11-12 19:29:51 -0800308 }
309 return mSubscriptionInfo;
310 }
311
Adrian Roos7861c662014-07-25 15:37:28 +0200312 @Override
313 public void onTrustManagedChanged(boolean managed, int userId) {
314 mUserTrustIsManaged.put(userId, managed);
315
316 for (int i = 0; i < mCallbacks.size(); i++) {
317 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
318 if (cb != null) {
319 cb.onTrustManagedChanged(userId);
320 }
321 }
322 }
323
Jim Miller9f0753f2015-03-23 23:59:22 -0700324 private void onFingerprintAuthenticated(int userId) {
325 mUserFingerprintAuthenticated.put(userId, true);
Jim Millerf41fc962014-06-18 16:33:51 -0700326 for (int i = 0; i < mCallbacks.size(); i++) {
327 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
328 if (cb != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700329 cb.onFingerprintAuthenticated(userId);
Jim Millerf41fc962014-06-18 16:33:51 -0700330 }
331 }
332 }
333
Jim Miller9f0753f2015-03-23 23:59:22 -0700334 private void handleFingerprintAuthenticated(int fingerId, int groupId) {
335 if (fingerId == 0) return; // not a valid fingerprint
Jim Millerf41fc962014-06-18 16:33:51 -0700336
337 final int userId;
338 try {
339 userId = ActivityManagerNative.getDefault().getCurrentUser().id;
340 } catch (RemoteException e) {
341 Log.e(TAG, "Failed to get current user id: ", e);
342 return;
343 }
Jim Miller06e34502014-07-17 14:46:05 -0700344 if (isFingerprintDisabled(userId)) {
345 Log.d(TAG, "Fingerprint disabled by DPM for userId: " + userId);
346 return;
347 }
Jim Millerf41fc962014-06-18 16:33:51 -0700348 final ContentResolver res = mContext.getContentResolver();
349 final int ids[] = FingerprintUtils.getFingerprintIdsForUser(res, userId);
350 for (int i = 0; i < ids.length; i++) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700351 // TODO: fix once HAL supports storing group id
352 final boolean isCorrectUser = true || (groupId == userId);
353 if (ids[i] == fingerId && isCorrectUser) {
354 onFingerprintAuthenticated(userId);
Jim Millerf41fc962014-06-18 16:33:51 -0700355 }
356 }
357 }
358
Jim Miller9f0753f2015-03-23 23:59:22 -0700359 private void handleFingerprintHelp(int msgId, String helpString) {
Jim Millerf41fc962014-06-18 16:33:51 -0700360 for (int i = 0; i < mCallbacks.size(); i++) {
361 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
362 if (cb != null) {
Jim Miller9f0753f2015-03-23 23:59:22 -0700363 cb.onFingerprintHelp(msgId, helpString);
364 }
365 }
366 }
367
368 private void handleFingerprintError(int msgId, String errString) {
369 for (int i = 0; i < mCallbacks.size(); i++) {
370 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
371 if (cb != null) {
372 cb.onFingerprintError(msgId, errString);
Jim Millerf41fc962014-06-18 16:33:51 -0700373 }
374 }
375 }
376
Adrian Roos4a410172014-08-20 17:41:44 +0200377 private void handleFaceUnlockStateChanged(boolean running, int userId) {
378 mUserFaceUnlockRunning.put(userId, running);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200379 for (int i = 0; i < mCallbacks.size(); i++) {
380 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
381 if (cb != null) {
Adrian Roos4a410172014-08-20 17:41:44 +0200382 cb.onFaceUnlockStateChanged(running, userId);
Jorim Jaggie7b12522014-08-06 16:41:21 +0200383 }
384 }
385 }
386
Adrian Roos4a410172014-08-20 17:41:44 +0200387 public boolean isFaceUnlockRunning(int userId) {
388 return mUserFaceUnlockRunning.get(userId);
389 }
390
Jim Miller50e62182014-04-23 17:25:00 -0700391 private boolean isTrustDisabled(int userId) {
Adrian Roosa4da9f62015-02-21 01:15:21 +0100392 // Don't allow trust agent if device is secured with a SIM PIN. This is here
393 // mainly because there's no other way to prompt the user to enter their SIM PIN
394 // once they get past the keyguard screen.
395 final boolean disabledBySimPin = isSimPinSecure();
396 return disabledBySimPin;
Jim Miller50e62182014-04-23 17:25:00 -0700397 }
398
Jim Miller06e34502014-07-17 14:46:05 -0700399 private boolean isFingerprintDisabled(int userId) {
400 final DevicePolicyManager dpm =
401 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE);
402 return dpm != null && (dpm.getKeyguardDisabledFeatures(null, userId)
403 & DevicePolicyManager.KEYGUARD_DISABLE_FINGERPRINT) != 0;
404 }
405
Adrian Roos46842d92014-03-27 14:58:03 +0100406 public boolean getUserHasTrust(int userId) {
Jim Millerf41fc962014-06-18 16:33:51 -0700407 return !isTrustDisabled(userId) && mUserHasTrust.get(userId)
Jim Miller9f0753f2015-03-23 23:59:22 -0700408 || mUserFingerprintAuthenticated.get(userId);
Adrian Roos46842d92014-03-27 14:58:03 +0100409 }
410
Adrian Roos7861c662014-07-25 15:37:28 +0200411 public boolean getUserTrustIsManaged(int userId) {
412 return mUserTrustIsManaged.get(userId) && !isTrustDisabled(userId);
413 }
414
Jim Miller8f09fd22013-03-14 19:04:28 -0700415 static class DisplayClientState {
416 public int clientGeneration;
417 public boolean clearing;
418 public PendingIntent intent;
419 public int playbackState;
420 public long playbackEventTime;
421 }
422
423 private DisplayClientState mDisplayClientState = new DisplayClientState();
424
Jim Millerbbf1a742012-07-17 18:30:30 -0700425 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
426
427 public void onReceive(Context context, Intent intent) {
428 final String action = intent.getAction();
429 if (DEBUG) Log.d(TAG, "received broadcast " + action);
430
431 if (Intent.ACTION_TIME_TICK.equals(action)
432 || Intent.ACTION_TIME_CHANGED.equals(action)
Adrian Roos48c796c2014-09-01 14:59:23 +0200433 || Intent.ACTION_TIMEZONE_CHANGED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700434 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
Jim Millerbbf1a742012-07-17 18:30:30 -0700435 } else if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
436 final int status = intent.getIntExtra(EXTRA_STATUS, BATTERY_STATUS_UNKNOWN);
437 final int plugged = intent.getIntExtra(EXTRA_PLUGGED, 0);
438 final int level = intent.getIntExtra(EXTRA_LEVEL, 0);
439 final int health = intent.getIntExtra(EXTRA_HEALTH, BATTERY_HEALTH_UNKNOWN);
440 final Message msg = mHandler.obtainMessage(
441 MSG_BATTERY_UPDATE, new BatteryStatus(status, level, plugged, health));
442 mHandler.sendMessage(msg);
443 } else if (TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(action)) {
Jim Miller52a61332014-11-12 19:29:51 -0800444 SimData args = SimData.fromIntent(intent);
Jim Millerbbf1a742012-07-17 18:30:30 -0700445 if (DEBUG_SIM_STATES) {
Jim Miller52a61332014-11-12 19:29:51 -0800446 Log.v(TAG, "action " + action
447 + " state: " + intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE)
448 + " slotId: " + args.slotId + " subid: " + args.subId);
Jim Millerbbf1a742012-07-17 18:30:30 -0700449 }
Jim Miller52a61332014-11-12 19:29:51 -0800450 mHandler.obtainMessage(MSG_SIM_STATE_CHANGE, args.subId, args.slotId, args.simState)
451 .sendToTarget();
Jim Millerbbf1a742012-07-17 18:30:30 -0700452 } else if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(action)) {
453 mHandler.sendMessage(mHandler.obtainMessage(MSG_RINGER_MODE_CHANGED,
454 intent.getIntExtra(AudioManager.EXTRA_RINGER_MODE, -1), 0));
455 } else if (TelephonyManager.ACTION_PHONE_STATE_CHANGED.equals(action)) {
456 String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
457 mHandler.sendMessage(mHandler.obtainMessage(MSG_PHONE_STATE_CHANGED, state));
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800458 } else if (Intent.ACTION_BOOT_COMPLETED.equals(action)) {
Jim Miller90873d52013-09-26 18:11:38 -0700459 dispatchBootCompleted();
Jim Millerbbf1a742012-07-17 18:30:30 -0700460 }
461 }
462 };
Jim Miller2de5ee82012-06-14 22:22:50 -0700463
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700464 private final BroadcastReceiver mBroadcastAllReceiver = new BroadcastReceiver() {
465
466 public void onReceive(Context context, Intent intent) {
467 final String action = intent.getAction();
Adrian Roos48c796c2014-09-01 14:59:23 +0200468 if (AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED.equals(action)) {
469 mHandler.sendEmptyMessage(MSG_TIME_UPDATE);
470 } else if (Intent.ACTION_USER_INFO_CHANGED.equals(action)) {
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700471 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_INFO_CHANGED,
472 intent.getIntExtra(Intent.EXTRA_USER_HANDLE, getSendingUserId()), 0));
Adrian Roos48c796c2014-09-01 14:59:23 +0200473 } else if (ACTION_FACE_UNLOCK_STARTED.equals(action)) {
474 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 1,
475 getSendingUserId()));
476 } else if (ACTION_FACE_UNLOCK_STOPPED.equals(action)) {
477 mHandler.sendMessage(mHandler.obtainMessage(MSG_FACE_UNLOCK_STATE_CHANGED, 0,
478 getSendingUserId()));
479 } else if (DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED
480 .equals(action)) {
481 mHandler.sendEmptyMessage(MSG_DPM_STATE_CHANGED);
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700482 }
483 }
484 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700485
486 private FingerprintManager.AuthenticationCallback mAuthenticationCallback
487 = new AuthenticationCallback() {
Jim Millerf41fc962014-06-18 16:33:51 -0700488
489 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700490 public void onAuthenticationSucceeded(AuthenticationResult result) {
491 mHandler.obtainMessage(MSG_FINGERPRINT_AUTHENTICATED,
492 result.getFingerprint().getFingerId(),
493 result.getFingerprint().getGroupId()).sendToTarget();
Jim Millerf41fc962014-06-18 16:33:51 -0700494 }
495
496 @Override
Jim Miller9f0753f2015-03-23 23:59:22 -0700497 public void onAuthenticationHelp(int helpMsgId, CharSequence helpString) {
498 mHandler.obtainMessage(MSG_FINGERPRINT_HELP, helpMsgId, 0, helpString).sendToTarget();
499 }
500
501 @Override
502 public void onAuthenticationError(int errMsgId, CharSequence errString) {
503 mHandler.obtainMessage(MSG_FINGERPRINT_ERROR, errMsgId, 0, errString);
Jim Millerf41fc962014-06-18 16:33:51 -0700504 }
505 };
Jim Miller9f0753f2015-03-23 23:59:22 -0700506 private CancellationSignal mFingerprintCancelSignal;
507 private FingerprintManager mFpm;
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700508
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800509 /**
Jim Miller47088bb2009-11-24 00:40:16 -0800510 * When we receive a
511 * {@link com.android.internal.telephony.TelephonyIntents#ACTION_SIM_STATE_CHANGED} broadcast,
Wink Saville37c124c2009-04-02 01:37:02 -0700512 * and then pass a result via our handler to {@link KeyguardUpdateMonitor#handleSimStateChange},
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800513 * we need a single object to pass to the handler. This class helps decode
Jim Miller47088bb2009-11-24 00:40:16 -0800514 * the intent and provide a {@link SimCard.State} result.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800515 */
Jim Miller52a61332014-11-12 19:29:51 -0800516 private static class SimData {
517 public State simState;
518 public int slotId;
519 public int subId;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800520
Jim Miller52a61332014-11-12 19:29:51 -0800521 SimData(State state, int slot, int id) {
Jim Miller90d5d462011-11-17 16:57:01 -0800522 simState = state;
Jim Miller52a61332014-11-12 19:29:51 -0800523 slotId = slot;
524 subId = id;
Jim Miller90d5d462011-11-17 16:57:01 -0800525 }
526
Jim Miller52a61332014-11-12 19:29:51 -0800527 static SimData fromIntent(Intent intent) {
528 State state;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800529 if (!TelephonyIntents.ACTION_SIM_STATE_CHANGED.equals(intent.getAction())) {
530 throw new IllegalArgumentException("only handles intent ACTION_SIM_STATE_CHANGED");
531 }
Wink Savillea639b312012-07-10 12:37:54 -0700532 String stateExtra = intent.getStringExtra(IccCardConstants.INTENT_KEY_ICC_STATE);
Jim Miller52a61332014-11-12 19:29:51 -0800533 int slotId = intent.getIntExtra(PhoneConstants.SLOT_KEY, 0);
534 int subId = intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY,
Wink Savilled09c4ca2014-11-22 10:08:16 -0800535 SubscriptionManager.INVALID_SUBSCRIPTION_ID);
Wink Savillea639b312012-07-10 12:37:54 -0700536 if (IccCardConstants.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) {
John Wangb0b24b32011-06-10 17:23:51 -0700537 final String absentReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700538 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
John Wangb0b24b32011-06-10 17:23:51 -0700539
Wink Savillea639b312012-07-10 12:37:54 -0700540 if (IccCardConstants.INTENT_VALUE_ABSENT_ON_PERM_DISABLED.equals(
John Wangb0b24b32011-06-10 17:23:51 -0700541 absentReason)) {
Wink Savillea639b312012-07-10 12:37:54 -0700542 state = IccCardConstants.State.PERM_DISABLED;
John Wangb0b24b32011-06-10 17:23:51 -0700543 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700544 state = IccCardConstants.State.ABSENT;
John Wangb0b24b32011-06-10 17:23:51 -0700545 }
Wink Savillea639b312012-07-10 12:37:54 -0700546 } else if (IccCardConstants.INTENT_VALUE_ICC_READY.equals(stateExtra)) {
547 state = IccCardConstants.State.READY;
548 } else if (IccCardConstants.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800549 final String lockedReason = intent
Wink Savillea639b312012-07-10 12:37:54 -0700550 .getStringExtra(IccCardConstants.INTENT_KEY_LOCKED_REASON);
551 if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) {
552 state = IccCardConstants.State.PIN_REQUIRED;
553 } else if (IccCardConstants.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) {
554 state = IccCardConstants.State.PUK_REQUIRED;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800555 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700556 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800557 }
Wink Savillea639b312012-07-10 12:37:54 -0700558 } else if (IccCardConstants.INTENT_VALUE_LOCKED_NETWORK.equals(stateExtra)) {
559 state = IccCardConstants.State.NETWORK_LOCKED;
Jim Miller109f1fd2012-09-19 20:44:16 -0700560 } else if (IccCardConstants.INTENT_VALUE_ICC_LOADED.equals(stateExtra)
561 || IccCardConstants.INTENT_VALUE_ICC_IMSI.equals(stateExtra)) {
562 // This is required because telephony doesn't return to "READY" after
563 // these state transitions. See bug 7197471.
564 state = IccCardConstants.State.READY;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800565 } else {
Wink Savillea639b312012-07-10 12:37:54 -0700566 state = IccCardConstants.State.UNKNOWN;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800567 }
Jim Miller52a61332014-11-12 19:29:51 -0800568 return new SimData(state, slotId, subId);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800569 }
570
571 public String toString() {
Jim Miller52a61332014-11-12 19:29:51 -0800572 return "SimData{state=" + simState + ",slotId=" + slotId + ",subId=" + subId + "}";
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800573 }
574 }
575
Adrian Roos12c1ef52014-06-04 13:54:08 +0200576 public static class BatteryStatus {
Jim Miller16464b82011-10-20 21:10:13 -0700577 public final int status;
578 public final int level;
579 public final int plugged;
580 public final int health;
581 public BatteryStatus(int status, int level, int plugged, int health) {
582 this.status = status;
583 this.level = level;
584 this.plugged = plugged;
585 this.health = health;
586 }
587
Jim Millerbbf1a742012-07-17 18:30:30 -0700588 /**
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700589 * Determine whether the device is plugged in (USB, power, or wireless).
Jim Millerbbf1a742012-07-17 18:30:30 -0700590 * @return true if the device is plugged in.
591 */
Adrian Roosad3bc7f2014-10-30 18:29:38 +0100592 public boolean isPluggedIn() {
Jim Millerbbf1a742012-07-17 18:30:30 -0700593 return plugged == BatteryManager.BATTERY_PLUGGED_AC
Brian Muramatsua92a01b2012-09-05 21:54:39 -0700594 || plugged == BatteryManager.BATTERY_PLUGGED_USB
595 || plugged == BatteryManager.BATTERY_PLUGGED_WIRELESS;
Jim Millerbbf1a742012-07-17 18:30:30 -0700596 }
597
598 /**
599 * Whether or not the device is charged. Note that some devices never return 100% for
600 * battery level, so this allows either battery level or status to determine if the
601 * battery is charged.
602 * @return true if the device is charged
603 */
604 public boolean isCharged() {
605 return status == BATTERY_STATUS_FULL || level >= 100;
606 }
607
608 /**
609 * Whether battery is low and needs to be charged.
610 * @return true if battery is low
611 */
612 public boolean isBatteryLow() {
613 return level < LOW_BATTERY_THRESHOLD;
614 }
615
Jim Miller16464b82011-10-20 21:10:13 -0700616 }
617
Jim Millerdcb3d842012-08-23 19:18:12 -0700618 public static KeyguardUpdateMonitor getInstance(Context context) {
619 if (sInstance == null) {
620 sInstance = new KeyguardUpdateMonitor(context);
621 }
622 return sInstance;
623 }
624
Jim Miller20daffd2013-10-07 14:59:53 -0700625 protected void handleScreenTurnedOn() {
626 final int count = mCallbacks.size();
627 for (int i = 0; i < count; i++) {
628 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
629 if (cb != null) {
630 cb.onScreenTurnedOn();
631 }
632 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700633 startListeningForFingerprint(mContext);
Jim Miller20daffd2013-10-07 14:59:53 -0700634 }
635
636 protected void handleScreenTurnedOff(int arg1) {
Jim Millerf41fc962014-06-18 16:33:51 -0700637 clearFingerprintRecognized();
Jim Miller20daffd2013-10-07 14:59:53 -0700638 final int count = mCallbacks.size();
639 for (int i = 0; i < count; i++) {
640 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
641 if (cb != null) {
642 cb.onScreenTurnedOff(arg1);
643 }
644 }
Jim Miller9f0753f2015-03-23 23:59:22 -0700645 stopListeningForFingerprint();
Jim Miller20daffd2013-10-07 14:59:53 -0700646 }
647
Adam Powell43a372f2013-09-27 17:43:53 -0700648 /**
649 * IMPORTANT: Must be called from UI thread.
650 */
651 public void dispatchSetBackground(Bitmap bmp) {
652 if (DEBUG) Log.d(TAG, "dispatchSetBackground");
653 final int count = mCallbacks.size();
654 for (int i = 0; i < count; i++) {
655 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
656 if (cb != null) {
657 cb.onSetBackground(bmp);
658 }
659 }
660 }
661
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700662 private void handleUserInfoChanged(int userId) {
663 for (int i = 0; i < mCallbacks.size(); i++) {
664 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
665 if (cb != null) {
666 cb.onUserInfoChanged(userId);
667 }
668 }
669 }
670
Jim Millerdcb3d842012-08-23 19:18:12 -0700671 private KeyguardUpdateMonitor(Context context) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800672 mContext = context;
Wink Savilled09c4ca2014-11-22 10:08:16 -0800673 mSubscriptionManager = SubscriptionManager.from(context);
Michael Jurkafff56142012-11-28 16:51:00 -0800674 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800675 // Since device can't be un-provisioned, we only need to register a content observer
676 // to update mDeviceProvisioned when we are...
677 if (!mDeviceProvisioned) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700678 watchForDeviceProvisioning();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800679 }
Jim Miller47088bb2009-11-24 00:40:16 -0800680
Jim Millerbbf1a742012-07-17 18:30:30 -0700681 // Take a guess at initial SIM state, battery status and PLMN until we get an update
Jim Miller16464b82011-10-20 21:10:13 -0700682 mBatteryStatus = new BatteryStatus(BATTERY_STATUS_UNKNOWN, 100, 0, 0);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800683
Jim Millerbbf1a742012-07-17 18:30:30 -0700684 // Watch for interesting updates
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800685 final IntentFilter filter = new IntentFilter();
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800686 filter.addAction(Intent.ACTION_TIME_TICK);
687 filter.addAction(Intent.ACTION_TIME_CHANGED);
688 filter.addAction(Intent.ACTION_BATTERY_CHANGED);
689 filter.addAction(Intent.ACTION_TIMEZONE_CHANGED);
690 filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED);
Jim Millerc23024d2010-02-24 15:37:00 -0800691 filter.addAction(TelephonyManager.ACTION_PHONE_STATE_CHANGED);
Jim Miller47088bb2009-11-24 00:40:16 -0800692 filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION);
Jim Millerbbf1a742012-07-17 18:30:30 -0700693 context.registerReceiver(mBroadcastReceiver, filter);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700694
Adam Cohenc276e822012-11-08 13:01:08 -0800695 final IntentFilter bootCompleteFilter = new IntentFilter();
696 bootCompleteFilter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
697 bootCompleteFilter.addAction(Intent.ACTION_BOOT_COMPLETED);
698 context.registerReceiver(mBroadcastReceiver, bootCompleteFilter);
699
Adrian Roos48c796c2014-09-01 14:59:23 +0200700 final IntentFilter allUserFilter = new IntentFilter();
701 allUserFilter.addAction(Intent.ACTION_USER_INFO_CHANGED);
702 allUserFilter.addAction(AlarmManager.ACTION_NEXT_ALARM_CLOCK_CHANGED);
703 allUserFilter.addAction(ACTION_FACE_UNLOCK_STARTED);
704 allUserFilter.addAction(ACTION_FACE_UNLOCK_STOPPED);
705 allUserFilter.addAction(DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED);
706 context.registerReceiverAsUser(mBroadcastAllReceiver, UserHandle.ALL, allUserFilter,
Amith Yamasani6fc1d4e2013-05-08 16:43:58 -0700707 null, null);
708
Wink Saville071743f2015-01-12 17:11:04 -0800709 mSubscriptionManager.addOnSubscriptionsChangedListener(mSubscriptionListener);
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700710 try {
711 ActivityManagerNative.getDefault().registerUserSwitchObserver(
712 new IUserSwitchObserver.Stub() {
713 @Override
714 public void onUserSwitching(int newUserId, IRemoteCallback reply) {
Chris Wrenf41c61b2012-11-29 15:19:54 -0500715 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCHING,
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700716 newUserId, 0, reply));
Brian Colonnaa5239892013-04-15 11:45:40 -0400717 mSwitchingUser = true;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700718 }
719 @Override
720 public void onUserSwitchComplete(int newUserId) throws RemoteException {
Chris Wrenf41c61b2012-11-29 15:19:54 -0500721 mHandler.sendMessage(mHandler.obtainMessage(MSG_USER_SWITCH_COMPLETE,
Adrian Roosbe47b072014-09-03 00:08:56 +0200722 newUserId, 0));
Brian Colonnaa5239892013-04-15 11:45:40 -0400723 mSwitchingUser = false;
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700724 }
Kenny Guy42979622015-04-13 18:03:05 +0000725 @Override
726 public void onForegroundProfileSwitch(int newProfileId) {
727 // Ignore.
728 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700729 });
730 } catch (RemoteException e) {
731 // TODO Auto-generated catch block
732 e.printStackTrace();
733 }
Adrian Roos46842d92014-03-27 14:58:03 +0100734
735 TrustManager trustManager = (TrustManager) context.getSystemService(Context.TRUST_SERVICE);
736 trustManager.registerTrustListener(this);
Jim Millerf41fc962014-06-18 16:33:51 -0700737
Jim Miller9f0753f2015-03-23 23:59:22 -0700738 mFpm = (FingerprintManager) context.getSystemService(Context.FINGERPRINT_SERVICE);
739 startListeningForFingerprint(context);
740 }
741
742 private void startListeningForFingerprint(Context context) {
743 if (mFpm != null && mFpm.isHardwareDetected()) {
744 if (mFingerprintCancelSignal == null) {
745 mFingerprintCancelSignal = new CancellationSignal();
746 } else {
747 mFingerprintCancelSignal.cancel();
748 }
749 mFpm.authenticate(null, mAuthenticationCallback, mFingerprintCancelSignal, 0);
750 }
751 }
752
753 private void stopListeningForFingerprint() {
754 if (mFingerprintCancelSignal != null) {
755 mFingerprintCancelSignal.cancel();
756 }
Jim Millerbbf1a742012-07-17 18:30:30 -0700757 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800758
Michael Jurkafff56142012-11-28 16:51:00 -0800759 private boolean isDeviceProvisionedInSettingsDb() {
760 return Settings.Global.getInt(mContext.getContentResolver(),
761 Settings.Global.DEVICE_PROVISIONED, 0) != 0;
762 }
763
Jim Millerbbf1a742012-07-17 18:30:30 -0700764 private void watchForDeviceProvisioning() {
Michael Jurkafff56142012-11-28 16:51:00 -0800765 mDeviceProvisionedObserver = new ContentObserver(mHandler) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700766 @Override
767 public void onChange(boolean selfChange) {
768 super.onChange(selfChange);
Michael Jurkafff56142012-11-28 16:51:00 -0800769 mDeviceProvisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -0700770 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -0700771 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800772 }
Jim Millerbbf1a742012-07-17 18:30:30 -0700773 if (DEBUG) Log.d(TAG, "DEVICE_PROVISIONED state = " + mDeviceProvisioned);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800774 }
Jim Millerbbf1a742012-07-17 18:30:30 -0700775 };
776
777 mContext.getContentResolver().registerContentObserver(
Jeff Brownbf6f6f92012-09-25 15:03:20 -0700778 Settings.Global.getUriFor(Settings.Global.DEVICE_PROVISIONED),
Michael Jurkafff56142012-11-28 16:51:00 -0800779 false, mDeviceProvisionedObserver);
Jim Millerbbf1a742012-07-17 18:30:30 -0700780
781 // prevent a race condition between where we check the flag and where we register the
782 // observer by grabbing the value once again...
Michael Jurkafff56142012-11-28 16:51:00 -0800783 boolean provisioned = isDeviceProvisionedInSettingsDb();
Jim Millerbbf1a742012-07-17 18:30:30 -0700784 if (provisioned != mDeviceProvisioned) {
785 mDeviceProvisioned = provisioned;
786 if (mDeviceProvisioned) {
Jim Miller90873d52013-09-26 18:11:38 -0700787 mHandler.sendEmptyMessage(MSG_DEVICE_PROVISIONED);
Jim Millerbbf1a742012-07-17 18:30:30 -0700788 }
789 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800790 }
791
Jim Millerbbf1a742012-07-17 18:30:30 -0700792 /**
793 * Handle {@link #MSG_DPM_STATE_CHANGED}
794 */
Jim Millerb0304762012-03-13 20:01:25 -0700795 protected void handleDevicePolicyManagerStateChanged() {
Jim Millerdcb3d842012-08-23 19:18:12 -0700796 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
797 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
798 if (cb != null) {
799 cb.onDevicePolicyManagerStateChanged();
800 }
Jim Millerb0304762012-03-13 20:01:25 -0700801 }
802 }
803
Jim Millerbbf1a742012-07-17 18:30:30 -0700804 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -0500805 * Handle {@link #MSG_USER_SWITCHING}
Jim Millerbbf1a742012-07-17 18:30:30 -0700806 */
Chris Wrenf41c61b2012-11-29 15:19:54 -0500807 protected void handleUserSwitching(int userId, IRemoteCallback reply) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700808 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700809 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
810 if (cb != null) {
Chris Wrenf41c61b2012-11-29 15:19:54 -0500811 cb.onUserSwitching(userId);
Jim Millerdcb3d842012-08-23 19:18:12 -0700812 }
Amith Yamasani52c489c2012-03-28 11:42:42 -0700813 }
Dianne Hackborn5dc5a002012-09-15 19:33:48 -0700814 try {
815 reply.sendResult(null);
816 } catch (RemoteException e) {
817 }
Amith Yamasani52c489c2012-03-28 11:42:42 -0700818 }
819
Jim Millerbbf1a742012-07-17 18:30:30 -0700820 /**
Chris Wrenf41c61b2012-11-29 15:19:54 -0500821 * Handle {@link #MSG_USER_SWITCH_COMPLETE}
822 */
823 protected void handleUserSwitchComplete(int userId) {
824 for (int i = 0; i < mCallbacks.size(); i++) {
825 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
826 if (cb != null) {
827 cb.onUserSwitchComplete(userId);
828 }
829 }
830 }
831
832 /**
Jim Miller90873d52013-09-26 18:11:38 -0700833 * This is exposed since {@link Intent#ACTION_BOOT_COMPLETED} is not sticky. If
834 * keyguard crashes sometime after boot, then it will never receive this
835 * broadcast and hence not handle the event. This method is ultimately called by
836 * PhoneWindowManager in this case.
837 */
Jorim Jaggi5cf17872014-03-26 18:31:48 +0100838 public void dispatchBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -0700839 mHandler.sendEmptyMessage(MSG_BOOT_COMPLETED);
Jim Miller90873d52013-09-26 18:11:38 -0700840 }
841
842 /**
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800843 * Handle {@link #MSG_BOOT_COMPLETED}
844 */
845 protected void handleBootCompleted() {
Jim Millere5f910a2013-10-16 18:15:46 -0700846 if (mBootCompleted) return;
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800847 mBootCompleted = true;
Adam Cohenefb3ffb2012-11-06 16:55:32 -0800848 for (int i = 0; i < mCallbacks.size(); i++) {
849 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
850 if (cb != null) {
851 cb.onBootCompleted();
852 }
853 }
854 }
855
856 /**
Jim Miller5ecd8112013-01-09 18:50:26 -0800857 * We need to store this state in the KeyguardUpdateMonitor since this class will not be
Adam Cohen4eb36cf2012-11-07 11:45:30 -0800858 * destroyed.
859 */
860 public boolean hasBootCompleted() {
861 return mBootCompleted;
862 }
863
864 /**
Jim Millerbbf1a742012-07-17 18:30:30 -0700865 * Handle {@link #MSG_DEVICE_PROVISIONED}
866 */
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700867 protected void handleDeviceProvisioned() {
Jim Millerbbf1a742012-07-17 18:30:30 -0700868 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700869 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
870 if (cb != null) {
871 cb.onDeviceProvisioned();
872 }
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700873 }
Michael Jurkafff56142012-11-28 16:51:00 -0800874 if (mDeviceProvisionedObserver != null) {
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700875 // We don't need the observer anymore...
Michael Jurkafff56142012-11-28 16:51:00 -0800876 mContext.getContentResolver().unregisterContentObserver(mDeviceProvisionedObserver);
877 mDeviceProvisionedObserver = null;
Nick Pelly24d7b5f2011-10-11 12:51:09 -0700878 }
879 }
880
Jim Millerbbf1a742012-07-17 18:30:30 -0700881 /**
882 * Handle {@link #MSG_PHONE_STATE_CHANGED}
883 */
Jim Millerc23024d2010-02-24 15:37:00 -0800884 protected void handlePhoneStateChanged(String newState) {
885 if (DEBUG) Log.d(TAG, "handlePhoneStateChanged(" + newState + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -0700886 if (TelephonyManager.EXTRA_STATE_IDLE.equals(newState)) {
887 mPhoneState = TelephonyManager.CALL_STATE_IDLE;
888 } else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(newState)) {
889 mPhoneState = TelephonyManager.CALL_STATE_OFFHOOK;
890 } else if (TelephonyManager.EXTRA_STATE_RINGING.equals(newState)) {
891 mPhoneState = TelephonyManager.CALL_STATE_RINGING;
892 }
Jim Millerbbf1a742012-07-17 18:30:30 -0700893 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700894 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
895 if (cb != null) {
896 cb.onPhoneStateChanged(mPhoneState);
897 }
Jim Millerc23024d2010-02-24 15:37:00 -0800898 }
899 }
900
Jim Millerbbf1a742012-07-17 18:30:30 -0700901 /**
902 * Handle {@link #MSG_RINGER_MODE_CHANGED}
903 */
Jim Miller47088bb2009-11-24 00:40:16 -0800904 protected void handleRingerModeChange(int mode) {
905 if (DEBUG) Log.d(TAG, "handleRingerModeChange(" + mode + ")");
Jim Miller3f5f83b2011-09-26 15:17:05 -0700906 mRingMode = mode;
Jim Millerbbf1a742012-07-17 18:30:30 -0700907 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700908 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
909 if (cb != null) {
910 cb.onRingerModeChanged(mode);
911 }
Jim Miller47088bb2009-11-24 00:40:16 -0800912 }
913 }
914
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800915 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800916 * Handle {@link #MSG_TIME_UPDATE}
917 */
918 private void handleTimeUpdate() {
919 if (DEBUG) Log.d(TAG, "handleTimeUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -0700920 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700921 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
922 if (cb != null) {
923 cb.onTimeChanged();
924 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800925 }
926 }
927
928 /**
929 * Handle {@link #MSG_BATTERY_UPDATE}
930 */
Jim Millerbbf1a742012-07-17 18:30:30 -0700931 private void handleBatteryUpdate(BatteryStatus status) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800932 if (DEBUG) Log.d(TAG, "handleBatteryUpdate");
Jim Millerbbf1a742012-07-17 18:30:30 -0700933 final boolean batteryUpdateInteresting = isBatteryUpdateInteresting(mBatteryStatus, status);
934 mBatteryStatus = status;
Jim Miller16464b82011-10-20 21:10:13 -0700935 if (batteryUpdateInteresting) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700936 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700937 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
938 if (cb != null) {
939 cb.onRefreshBatteryInfo(status);
940 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800941 }
942 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800943 }
944
945 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800946 * Handle {@link #MSG_SIM_STATE_CHANGE}
947 */
Jim Miller52a61332014-11-12 19:29:51 -0800948 private void handleSimStateChange(int subId, int slotId, State state) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800949
Jim Miller52a61332014-11-12 19:29:51 -0800950 if (DEBUG_SIM_STATES) {
951 Log.d(TAG, "handleSimStateChange(subId=" + subId + ", slotId="
952 + slotId + ", state=" + state +")");
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800953 }
954
Wink Savillea54bf652014-12-11 13:37:50 -0800955 if (!SubscriptionManager.isValidSubscriptionId(subId)) {
Jim Miller52a61332014-11-12 19:29:51 -0800956 Log.w(TAG, "invalid subId in handleSimStateChange()");
957 return;
958 }
959
960 SimData data = mSimDatas.get(subId);
961 final boolean changed;
962 if (data == null) {
963 data = new SimData(state, slotId, subId);
964 mSimDatas.put(subId, data);
965 changed = true; // no data yet; force update
966 } else {
967 changed = (data.simState != state || data.subId != subId || data.slotId != slotId);
968 data.simState = state;
969 data.subId = subId;
970 data.slotId = slotId;
971 }
972 if (changed && state != State.UNKNOWN) {
Jim Millerbbf1a742012-07-17 18:30:30 -0700973 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700974 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
975 if (cb != null) {
Jim Miller52a61332014-11-12 19:29:51 -0800976 cb.onSimStateChanged(subId, slotId, state);
Jim Millerdcb3d842012-08-23 19:18:12 -0700977 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -0800978 }
979 }
980 }
981
Jim Millerbbf1a742012-07-17 18:30:30 -0700982 /**
983 * Handle {@link #MSG_CLOCK_VISIBILITY_CHANGED}
984 */
Jeff Sharkey054340d2011-09-01 22:28:03 -0700985 private void handleClockVisibilityChanged() {
986 if (DEBUG) Log.d(TAG, "handleClockVisibilityChanged()");
Jim Millerbbf1a742012-07-17 18:30:30 -0700987 for (int i = 0; i < mCallbacks.size(); i++) {
Jim Millerdcb3d842012-08-23 19:18:12 -0700988 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
989 if (cb != null) {
990 cb.onClockVisibilityChanged();
991 }
Jeff Sharkey054340d2011-09-01 22:28:03 -0700992 }
993 }
994
Danielle Millettf6d0fc12012-10-23 16:16:52 -0400995 /**
996 * Handle {@link #MSG_KEYGUARD_VISIBILITY_CHANGED}
997 */
998 private void handleKeyguardVisibilityChanged(int showing) {
999 if (DEBUG) Log.d(TAG, "handleKeyguardVisibilityChanged(" + showing + ")");
Danielle Millett5d2404d2012-11-01 00:05:27 -04001000 boolean isShowing = (showing == 1);
1001 mKeyguardIsVisible = isShowing;
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001002 for (int i = 0; i < mCallbacks.size(); i++) {
1003 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1004 if (cb != null) {
John Spurlock385a63d2013-10-30 19:40:48 -04001005 cb.onKeyguardVisibilityChangedRaw(isShowing);
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001006 }
1007 }
1008 }
1009
Brian Colonna7fce3802013-09-17 15:51:32 -04001010 /**
Adrian Roosb6011622014-05-14 15:52:53 +02001011 * Handle {@link #MSG_KEYGUARD_BOUNCER_CHANGED}
1012 * @see #sendKeyguardBouncerChanged(boolean)
1013 */
1014 private void handleKeyguardBouncerChanged(int bouncer) {
1015 if (DEBUG) Log.d(TAG, "handleKeyguardBouncerChanged(" + bouncer + ")");
1016 boolean isBouncer = (bouncer == 1);
1017 mBouncer = isBouncer;
1018 for (int i = 0; i < mCallbacks.size(); i++) {
1019 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1020 if (cb != null) {
1021 cb.onKeyguardBouncerChanged(isBouncer);
1022 }
1023 }
1024 }
1025
1026 /**
Brian Colonna7fce3802013-09-17 15:51:32 -04001027 * Handle {@link #MSG_REPORT_EMERGENCY_CALL_ACTION}
1028 */
1029 private void handleReportEmergencyCallAction() {
1030 for (int i = 0; i < mCallbacks.size(); i++) {
1031 KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
1032 if (cb != null) {
1033 cb.onEmergencyCallAction();
1034 }
1035 }
1036 }
1037
Danielle Millett5d2404d2012-11-01 00:05:27 -04001038 public boolean isKeyguardVisible() {
1039 return mKeyguardIsVisible;
1040 }
1041
Adrian Roosb6011622014-05-14 15:52:53 +02001042 /**
1043 * @return if the keyguard is currently in bouncer mode.
1044 */
1045 public boolean isKeyguardBouncer() {
1046 return mBouncer;
1047 }
1048
Brian Colonnaa5239892013-04-15 11:45:40 -04001049 public boolean isSwitchingUser() {
1050 return mSwitchingUser;
1051 }
1052
Jim Miller16464b82011-10-20 21:10:13 -07001053 private static boolean isBatteryUpdateInteresting(BatteryStatus old, BatteryStatus current) {
Jim Millerbbf1a742012-07-17 18:30:30 -07001054 final boolean nowPluggedIn = current.isPluggedIn();
1055 final boolean wasPluggedIn = old.isPluggedIn();
Jim Miller79a444a2011-02-15 15:02:11 -08001056 final boolean stateChangedWhilePluggedIn =
Jim Miller16464b82011-10-20 21:10:13 -07001057 wasPluggedIn == true && nowPluggedIn == true
1058 && (old.status != current.status);
1059
1060 // change in plug state is always interesting
1061 if (wasPluggedIn != nowPluggedIn || stateChangedWhilePluggedIn) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001062 return true;
1063 }
1064
1065 // change in battery level while plugged in
Jim Miller16464b82011-10-20 21:10:13 -07001066 if (nowPluggedIn && old.level != current.level) {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001067 return true;
1068 }
1069
Jim Miller16464b82011-10-20 21:10:13 -07001070 // change where battery needs charging
Jim Millerbbf1a742012-07-17 18:30:30 -07001071 if (!nowPluggedIn && current.isBatteryLow() && current.level != old.level) {
Jim Miller16464b82011-10-20 21:10:13 -07001072 return true;
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001073 }
1074 return false;
1075 }
1076
1077 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001078 * @return The default plmn (no service)
1079 */
1080 private CharSequence getDefaultPlmn() {
Jim Miller5ecd8112013-01-09 18:50:26 -08001081 return mContext.getResources().getText(R.string.keyguard_carrier_default);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001082 }
1083
1084 /**
Jim Millerbbf1a742012-07-17 18:30:30 -07001085 * Remove the given observer's callback.
1086 *
Jim Miller6212cc02012-09-05 17:35:31 -07001087 * @param callback The callback to remove
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001088 */
Jim Miller6212cc02012-09-05 17:35:31 -07001089 public void removeCallback(KeyguardUpdateMonitorCallback callback) {
1090 if (DEBUG) Log.v(TAG, "*** unregister callback for " + callback);
1091 for (int i = mCallbacks.size() - 1; i >= 0; i--) {
1092 if (mCallbacks.get(i).get() == callback) {
1093 mCallbacks.remove(i);
1094 }
1095 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001096 }
1097
1098 /**
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001099 * Register to receive notifications about general keyguard information
1100 * (see {@link InfoCallback}.
Jim Miller6212cc02012-09-05 17:35:31 -07001101 * @param callback The callback to register
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001102 */
Jim Millerbbf1a742012-07-17 18:30:30 -07001103 public void registerCallback(KeyguardUpdateMonitorCallback callback) {
Jim Miller6212cc02012-09-05 17:35:31 -07001104 if (DEBUG) Log.v(TAG, "*** register callback for " + callback);
1105 // Prevent adding duplicate callbacks
1106 for (int i = 0; i < mCallbacks.size(); i++) {
1107 if (mCallbacks.get(i).get() == callback) {
1108 if (DEBUG) Log.e(TAG, "Object tried to add another callback",
1109 new Exception("Called by"));
1110 return;
Jim Millerdcb3d842012-08-23 19:18:12 -07001111 }
1112 }
Jim Miller6212cc02012-09-05 17:35:31 -07001113 mCallbacks.add(new WeakReference<KeyguardUpdateMonitorCallback>(callback));
1114 removeCallback(null); // remove unused references
1115 sendUpdates(callback);
1116 }
1117
1118 private void sendUpdates(KeyguardUpdateMonitorCallback callback) {
1119 // Notify listener of the current state
1120 callback.onRefreshBatteryInfo(mBatteryStatus);
1121 callback.onTimeChanged();
1122 callback.onRingerModeChanged(mRingMode);
1123 callback.onPhoneStateChanged(mPhoneState);
Jason Monk9ff69bd2014-12-02 16:43:17 -05001124 callback.onRefreshCarrierInfo();
Jim Miller6212cc02012-09-05 17:35:31 -07001125 callback.onClockVisibilityChanged();
Jim Miller52a61332014-11-12 19:29:51 -08001126 for (Entry<Integer, SimData> data : mSimDatas.entrySet()) {
1127 final SimData state = data.getValue();
1128 callback.onSimStateChanged(state.subId, state.slotId, state.simState);
1129 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001130 }
1131
Danielle Millettf6d0fc12012-10-23 16:16:52 -04001132 public void sendKeyguardVisibilityChanged(boolean showing) {
1133 if (DEBUG) Log.d(TAG, "sendKeyguardVisibilityChanged(" + showing + ")");
1134 Message message = mHandler.obtainMessage(MSG_KEYGUARD_VISIBILITY_CHANGED);
1135 message.arg1 = showing ? 1 : 0;
1136 message.sendToTarget();
1137 }
1138
Adrian Roosb6011622014-05-14 15:52:53 +02001139 /**
1140 * @see #handleKeyguardBouncerChanged(int)
1141 */
1142 public void sendKeyguardBouncerChanged(boolean showingBouncer) {
1143 if (DEBUG) Log.d(TAG, "sendKeyguardBouncerChanged(" + showingBouncer + ")");
1144 Message message = mHandler.obtainMessage(MSG_KEYGUARD_BOUNCER_CHANGED);
1145 message.arg1 = showingBouncer ? 1 : 0;
1146 message.sendToTarget();
1147 }
1148
Jeff Sharkey054340d2011-09-01 22:28:03 -07001149 public void reportClockVisible(boolean visible) {
1150 mClockVisible = visible;
1151 mHandler.obtainMessage(MSG_CLOCK_VISIBILITY_CHANGED).sendToTarget();
1152 }
1153
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001154 /**
Jim Miller90d5d462011-11-17 16:57:01 -08001155 * 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 -08001156 * have the information earlier than waiting for the intent
1157 * broadcast from the telephony code.
Jim Miller90d5d462011-11-17 16:57:01 -08001158 *
1159 * NOTE: Because handleSimStateChange() invokes callbacks immediately without going
1160 * through mHandler, this *must* be called from the UI thread.
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001161 */
Jim Miller52a61332014-11-12 19:29:51 -08001162 public void reportSimUnlocked(int subId) {
1163 if (DEBUG_SIM_STATES) Log.v(TAG, "reportSimUnlocked(subId=" + subId + ")");
1164 int slotId = SubscriptionManager.getSlotId(subId);
1165 handleSimStateChange(subId, slotId, State.READY);
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001166 }
1167
Brian Colonna7fce3802013-09-17 15:51:32 -04001168 /**
1169 * Report that the emergency call button has been pressed and the emergency dialer is
1170 * about to be displayed.
1171 *
1172 * @param bypassHandler runs immediately.
1173 *
1174 * NOTE: Must be called from UI thread if bypassHandler == true.
1175 */
1176 public void reportEmergencyCallAction(boolean bypassHandler) {
1177 if (!bypassHandler) {
1178 mHandler.obtainMessage(MSG_REPORT_EMERGENCY_CALL_ACTION).sendToTarget();
1179 } else {
1180 handleReportEmergencyCallAction();
1181 }
1182 }
1183
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001184 /**
1185 * @return Whether the device is provisioned (whether they have gone through
1186 * the setup wizard)
1187 */
1188 public boolean isDeviceProvisioned() {
1189 return mDeviceProvisioned;
1190 }
1191
Jim Miller258341c2012-08-30 16:50:10 -07001192 public int getFailedUnlockAttempts() {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001193 return mFailedAttempts;
1194 }
1195
Jim Miller258341c2012-08-30 16:50:10 -07001196 public void clearFailedUnlockAttempts() {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001197 mFailedAttempts = 0;
1198 }
1199
Jim Millerf41fc962014-06-18 16:33:51 -07001200 public void clearFingerprintRecognized() {
Jim Miller9f0753f2015-03-23 23:59:22 -07001201 mUserFingerprintAuthenticated.clear();
Jim Millerf41fc962014-06-18 16:33:51 -07001202 }
1203
Jim Miller258341c2012-08-30 16:50:10 -07001204 public void reportFailedUnlockAttempt() {
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001205 mFailedAttempts++;
1206 }
Jim Miller1c188282011-08-08 22:27:58 -07001207
Jeff Sharkey054340d2011-09-01 22:28:03 -07001208 public boolean isClockVisible() {
1209 return mClockVisible;
1210 }
1211
Brian Colonna267cb2b2011-09-26 13:52:25 -04001212 public int getPhoneState() {
1213 return mPhoneState;
1214 }
Steven Rossb9430d22011-11-23 07:54:09 -05001215
Jim Miller52a61332014-11-12 19:29:51 -08001216 public boolean isSimPinVoiceSecure() {
1217 // TODO: only count SIMs that handle voice
1218 return isSimPinSecure();
Jim Millerdcb3d842012-08-23 19:18:12 -07001219 }
1220
1221 public boolean isSimPinSecure() {
Jim Miller52a61332014-11-12 19:29:51 -08001222 // True if any SIM is pin secure
1223 for (SubscriptionInfo info : getSubscriptionInfo(false /* forceReload */)) {
1224 if (isSimPinSecure(getSimState(info.getSubscriptionId()))) return true;
1225 }
1226 return false;
1227 }
1228
Jason Monk9ff69bd2014-12-02 16:43:17 -05001229 public State getSimState(int subId) {
Jim Miller52a61332014-11-12 19:29:51 -08001230 if (mSimDatas.containsKey(subId)) {
1231 return mSimDatas.get(subId).simState;
1232 } else {
1233 return State.UNKNOWN;
1234 }
1235 }
1236
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001237 /**
1238 * @return true if and only if the state has changed for the specified {@code slotId}
1239 */
1240 private boolean refreshSimState(int subId, int slotId) {
Jim Miller52a61332014-11-12 19:29:51 -08001241
1242 // This is awful. It exists because there are two APIs for getting the SIM status
1243 // that don't return the complete set of values and have different types. In Keyguard we
1244 // need IccCardConstants, but TelephonyManager would only give us
1245 // TelephonyManager.SIM_STATE*, so we retrieve it manually.
xinhe18b9c3c2014-12-02 15:03:20 -08001246 final TelephonyManager tele = TelephonyManager.from(mContext);
1247 int simState = tele.getSimState(slotId);
Jim Miller52a61332014-11-12 19:29:51 -08001248 State state;
1249 try {
xinhe18b9c3c2014-12-02 15:03:20 -08001250 state = State.intToState(simState);
Jim Miller52a61332014-11-12 19:29:51 -08001251 } catch(IllegalArgumentException ex) {
xinhe18b9c3c2014-12-02 15:03:20 -08001252 Log.w(TAG, "Unknown sim state: " + simState);
Jim Miller52a61332014-11-12 19:29:51 -08001253 state = State.UNKNOWN;
John Spurlock5b13e922015-01-07 11:04:58 -05001254 }
Jorim Jaggi01ba98b2015-01-13 21:33:45 +01001255 SimData data = mSimDatas.get(subId);
1256 final boolean changed;
1257 if (data == null) {
1258 data = new SimData(state, slotId, subId);
1259 mSimDatas.put(subId, data);
1260 changed = true; // no data yet; force update
1261 } else {
1262 changed = data.simState != state;
1263 data.simState = state;
1264 }
1265 return changed;
Jim Millerdcb3d842012-08-23 19:18:12 -07001266 }
1267
1268 public static boolean isSimPinSecure(IccCardConstants.State state) {
1269 final IccCardConstants.State simState = state;
1270 return (simState == IccCardConstants.State.PIN_REQUIRED
1271 || simState == IccCardConstants.State.PUK_REQUIRED
1272 || simState == IccCardConstants.State.PERM_DISABLED);
Jim Millerb0304762012-03-13 20:01:25 -07001273 }
Jim Miller8f09fd22013-03-14 19:04:28 -07001274
1275 public DisplayClientState getCachedDisplayClientState() {
1276 return mDisplayClientState;
1277 }
Jim Miller20daffd2013-10-07 14:59:53 -07001278
1279 // TODO: use these callbacks elsewhere in place of the existing notifyScreen*()
1280 // (KeyguardViewMediator, KeyguardHostView)
1281 public void dispatchScreenTurnedOn() {
1282 synchronized (this) {
1283 mScreenOn = true;
1284 }
1285 mHandler.sendEmptyMessage(MSG_SCREEN_TURNED_ON);
1286 }
1287
John Spurlock36a13422015-03-24 21:15:48 -04001288 public void dispatchScreenTurnedOff(int why) {
Jim Miller20daffd2013-10-07 14:59:53 -07001289 synchronized(this) {
1290 mScreenOn = false;
1291 }
1292 mHandler.sendMessage(mHandler.obtainMessage(MSG_SCREEN_TURNED_OFF, why, 0));
1293 }
1294
1295 public boolean isScreenOn() {
1296 return mScreenOn;
1297 }
Jim Miller52a61332014-11-12 19:29:51 -08001298
1299 /**
1300 * Find the next SubscriptionId for a SIM in the given state, favoring lower slot numbers first.
1301 * @param state
Wink Savilled09c4ca2014-11-22 10:08:16 -08001302 * @return subid or {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID} if none found
Jim Miller52a61332014-11-12 19:29:51 -08001303 */
1304 public int getNextSubIdForState(State state) {
1305 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
Wink Savilled09c4ca2014-11-22 10:08:16 -08001306 int resultId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jim Miller52a61332014-11-12 19:29:51 -08001307 int bestSlotId = Integer.MAX_VALUE; // Favor lowest slot first
1308 for (int i = 0; i < list.size(); i++) {
1309 final SubscriptionInfo info = list.get(i);
1310 final int id = info.getSubscriptionId();
1311 int slotId = SubscriptionManager.getSlotId(id);
1312 if (state == getSimState(id) && bestSlotId > slotId ) {
1313 resultId = id;
1314 bestSlotId = slotId;
1315 }
1316 }
1317 return resultId;
1318 }
1319
1320 public SubscriptionInfo getSubscriptionInfoForSubId(int subId) {
1321 List<SubscriptionInfo> list = getSubscriptionInfo(false /* forceReload */);
1322 for (int i = 0; i < list.size(); i++) {
1323 SubscriptionInfo info = list.get(i);
1324 if (subId == info.getSubscriptionId()) return info;
1325 }
1326 return null; // not found
1327 }
The Android Open Source Project1f838aa2009-03-03 19:32:13 -08001328}