1 /* 2 * Copyright (C) 2015 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 17 package com.android.server.locksettings; 18 19 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_NOT_REQUIRED; 20 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT; 21 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT; 22 23 import android.app.AlarmManager; 24 import android.app.AlarmManager.OnAlarmListener; 25 import android.app.admin.DevicePolicyManager; 26 import android.app.trust.IStrongAuthTracker; 27 import android.content.Context; 28 import android.os.Handler; 29 import android.os.Looper; 30 import android.os.Message; 31 import android.os.RemoteCallbackList; 32 import android.os.RemoteException; 33 import android.os.SystemClock; 34 import android.os.UserHandle; 35 import android.util.ArrayMap; 36 import android.util.Slog; 37 import android.util.SparseBooleanArray; 38 import android.util.SparseIntArray; 39 40 import com.android.internal.annotations.VisibleForTesting; 41 import com.android.internal.util.IndentingPrintWriter; 42 import com.android.internal.widget.LockPatternUtils.StrongAuthTracker; 43 44 /** 45 * Keeps track of requests for strong authentication. 46 */ 47 public class LockSettingsStrongAuth { 48 49 private static final String TAG = "LockSettings"; 50 private static final boolean DEBUG = false; 51 52 private static final int MSG_REQUIRE_STRONG_AUTH = 1; 53 private static final int MSG_REGISTER_TRACKER = 2; 54 private static final int MSG_UNREGISTER_TRACKER = 3; 55 private static final int MSG_REMOVE_USER = 4; 56 private static final int MSG_SCHEDULE_STRONG_AUTH_TIMEOUT = 5; 57 private static final int MSG_NO_LONGER_REQUIRE_STRONG_AUTH = 6; 58 private static final int MSG_SCHEDULE_NON_STRONG_BIOMETRIC_TIMEOUT = 7; 59 private static final int MSG_STRONG_BIOMETRIC_UNLOCK = 8; 60 private static final int MSG_SCHEDULE_NON_STRONG_BIOMETRIC_IDLE_TIMEOUT = 9; 61 private static final int MSG_REFRESH_STRONG_AUTH_TIMEOUT = 10; 62 63 @VisibleForTesting 64 protected static final String STRONG_AUTH_TIMEOUT_ALARM_TAG = 65 "LockSettingsStrongAuth.timeoutForUser"; 66 @VisibleForTesting 67 protected static final String NON_STRONG_BIOMETRIC_TIMEOUT_ALARM_TAG = 68 "LockSettingsPrimaryAuth.nonStrongBiometricTimeoutForUser"; 69 @VisibleForTesting 70 protected static final String NON_STRONG_BIOMETRIC_IDLE_TIMEOUT_ALARM_TAG = 71 "LockSettingsPrimaryAuth.nonStrongBiometricIdleTimeoutForUser"; 72 73 /** 74 * Default and maximum timeout in milliseconds after which unlocking with weak auth times out, 75 * i.e. the user has to use a strong authentication method like password, PIN or pattern. 76 */ 77 public static final long DEFAULT_NON_STRONG_BIOMETRIC_TIMEOUT_MS = 24 * 60 * 60 * 1000; // 24h 78 public static final long DEFAULT_NON_STRONG_BIOMETRIC_IDLE_TIMEOUT_MS = 79 4 * 60 * 60 * 1000; // 4h 80 81 private final RemoteCallbackList<IStrongAuthTracker> mTrackers = new RemoteCallbackList<>(); 82 @VisibleForTesting 83 protected final SparseIntArray mStrongAuthForUser = new SparseIntArray(); 84 @VisibleForTesting 85 protected final SparseBooleanArray mIsNonStrongBiometricAllowedForUser = 86 new SparseBooleanArray(); 87 @VisibleForTesting 88 protected final ArrayMap<Integer, StrongAuthTimeoutAlarmListener> 89 mStrongAuthTimeoutAlarmListenerForUser = new ArrayMap<>(); 90 // Track non-strong biometric timeout 91 @VisibleForTesting 92 protected final ArrayMap<Integer, NonStrongBiometricTimeoutAlarmListener> 93 mNonStrongBiometricTimeoutAlarmListener = new ArrayMap<>(); 94 // Track non-strong biometric idle timeout 95 @VisibleForTesting 96 protected final ArrayMap<Integer, NonStrongBiometricIdleTimeoutAlarmListener> 97 mNonStrongBiometricIdleTimeoutAlarmListener = new ArrayMap<>(); 98 99 private final int mDefaultStrongAuthFlags; 100 private final boolean mDefaultIsNonStrongBiometricAllowed = true; 101 102 private final Context mContext; 103 private final Injector mInjector; 104 private final AlarmManager mAlarmManager; 105 LockSettingsStrongAuth(Context context)106 public LockSettingsStrongAuth(Context context) { 107 this(context, new Injector()); 108 } 109 110 @VisibleForTesting LockSettingsStrongAuth(Context context, Injector injector)111 protected LockSettingsStrongAuth(Context context, Injector injector) { 112 mContext = context; 113 mInjector = injector; 114 mDefaultStrongAuthFlags = mInjector.getDefaultStrongAuthFlags(context); 115 mAlarmManager = mInjector.getAlarmManager(context); 116 } 117 118 /** 119 * Class for injecting dependencies into LockSettingsStrongAuth. 120 */ 121 @VisibleForTesting 122 public static class Injector { 123 124 /** 125 * Allows to mock AlarmManager for testing. 126 */ 127 @VisibleForTesting getAlarmManager(Context context)128 public AlarmManager getAlarmManager(Context context) { 129 return context.getSystemService(AlarmManager.class); 130 } 131 132 /** 133 * Allows to get different default StrongAuthFlags for testing. 134 */ 135 @VisibleForTesting getDefaultStrongAuthFlags(Context context)136 public int getDefaultStrongAuthFlags(Context context) { 137 return StrongAuthTracker.getDefaultFlags(context); 138 } 139 140 /** 141 * Allows to get different triggerAtMillis values when setting alarms for testing. 142 */ 143 @VisibleForTesting getNextAlarmTimeMs(long timeout)144 public long getNextAlarmTimeMs(long timeout) { 145 return SystemClock.elapsedRealtime() + timeout; 146 } 147 148 /** 149 * Wraps around {@link SystemClock#elapsedRealtime}, which returns the number of 150 * milliseconds since boot, including time spent in sleep. 151 */ 152 @VisibleForTesting getElapsedRealtimeMs()153 public long getElapsedRealtimeMs() { 154 return SystemClock.elapsedRealtime(); 155 } 156 } 157 handleAddStrongAuthTracker(IStrongAuthTracker tracker)158 private void handleAddStrongAuthTracker(IStrongAuthTracker tracker) { 159 mTrackers.register(tracker); 160 161 for (int i = 0; i < mStrongAuthForUser.size(); i++) { 162 int key = mStrongAuthForUser.keyAt(i); 163 int value = mStrongAuthForUser.valueAt(i); 164 try { 165 tracker.onStrongAuthRequiredChanged(value, key); 166 } catch (RemoteException e) { 167 Slog.e(TAG, "Exception while adding StrongAuthTracker.", e); 168 } 169 } 170 171 for (int i = 0; i < mIsNonStrongBiometricAllowedForUser.size(); i++) { 172 int key = mIsNonStrongBiometricAllowedForUser.keyAt(i); 173 boolean value = mIsNonStrongBiometricAllowedForUser.valueAt(i); 174 try { 175 tracker.onIsNonStrongBiometricAllowedChanged(value, key); 176 } catch (RemoteException e) { 177 Slog.e(TAG, "Exception while adding StrongAuthTracker: " 178 + "IsNonStrongBiometricAllowedChanged.", e); 179 } 180 } 181 } 182 handleRemoveStrongAuthTracker(IStrongAuthTracker tracker)183 private void handleRemoveStrongAuthTracker(IStrongAuthTracker tracker) { 184 mTrackers.unregister(tracker); 185 } 186 handleRequireStrongAuth(int strongAuthReason, int userId)187 private void handleRequireStrongAuth(int strongAuthReason, int userId) { 188 if (userId == UserHandle.USER_ALL) { 189 for (int i = 0; i < mStrongAuthForUser.size(); i++) { 190 int key = mStrongAuthForUser.keyAt(i); 191 handleRequireStrongAuthOneUser(strongAuthReason, key); 192 } 193 } else { 194 handleRequireStrongAuthOneUser(strongAuthReason, userId); 195 } 196 } 197 handleRequireStrongAuthOneUser(int strongAuthReason, int userId)198 private void handleRequireStrongAuthOneUser(int strongAuthReason, int userId) { 199 int oldValue = mStrongAuthForUser.get(userId, mDefaultStrongAuthFlags); 200 int newValue = strongAuthReason == STRONG_AUTH_NOT_REQUIRED 201 ? STRONG_AUTH_NOT_REQUIRED 202 : (oldValue | strongAuthReason); 203 if (oldValue != newValue) { 204 mStrongAuthForUser.put(userId, newValue); 205 notifyStrongAuthTrackers(newValue, userId); 206 } 207 } 208 handleNoLongerRequireStrongAuth(int strongAuthReason, int userId)209 private void handleNoLongerRequireStrongAuth(int strongAuthReason, int userId) { 210 if (userId == UserHandle.USER_ALL) { 211 for (int i = 0; i < mStrongAuthForUser.size(); i++) { 212 int key = mStrongAuthForUser.keyAt(i); 213 handleNoLongerRequireStrongAuthOneUser(strongAuthReason, key); 214 } 215 } else { 216 handleNoLongerRequireStrongAuthOneUser(strongAuthReason, userId); 217 } 218 } 219 handleNoLongerRequireStrongAuthOneUser(int strongAuthReason, int userId)220 private void handleNoLongerRequireStrongAuthOneUser(int strongAuthReason, int userId) { 221 int oldValue = mStrongAuthForUser.get(userId, mDefaultStrongAuthFlags); 222 int newValue = oldValue & ~strongAuthReason; 223 if (oldValue != newValue) { 224 mStrongAuthForUser.put(userId, newValue); 225 notifyStrongAuthTrackers(newValue, userId); 226 } 227 } 228 handleRemoveUser(int userId)229 private void handleRemoveUser(int userId) { 230 int index = mStrongAuthForUser.indexOfKey(userId); 231 if (index >= 0) { 232 mStrongAuthForUser.removeAt(index); 233 notifyStrongAuthTrackers(mDefaultStrongAuthFlags, userId); 234 } 235 236 index = mIsNonStrongBiometricAllowedForUser.indexOfKey(userId); 237 if (index >= 0) { 238 mIsNonStrongBiometricAllowedForUser.removeAt(index); 239 notifyStrongAuthTrackersForIsNonStrongBiometricAllowed( 240 mDefaultIsNonStrongBiometricAllowed, userId); 241 } 242 } 243 244 /** 245 * Re-schedule the strong auth timeout alarm with latest information on the most recent 246 * successful strong auth time and strong auth timeout from device policy. 247 */ rescheduleStrongAuthTimeoutAlarm(long strongAuthTime, int userId)248 private void rescheduleStrongAuthTimeoutAlarm(long strongAuthTime, int userId) { 249 final DevicePolicyManager dpm = 250 (DevicePolicyManager) mContext.getSystemService(Context.DEVICE_POLICY_SERVICE); 251 // cancel current alarm listener for the user (if there was one) 252 StrongAuthTimeoutAlarmListener alarm = mStrongAuthTimeoutAlarmListenerForUser.get(userId); 253 if (alarm != null) { 254 mAlarmManager.cancel(alarm); 255 alarm.setLatestStrongAuthTime(strongAuthTime); 256 } else { 257 alarm = new StrongAuthTimeoutAlarmListener(strongAuthTime, userId); 258 mStrongAuthTimeoutAlarmListenerForUser.put(userId, alarm); 259 } 260 // AlarmManager.set() correctly handles the case where nextAlarmTime has already been in 261 // the past (by firing the listener straight away), so nothing special for us to do here. 262 long nextAlarmTime = strongAuthTime + dpm.getRequiredStrongAuthTimeout(null, userId); 263 264 // schedule a new alarm listener for the user 265 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, nextAlarmTime, 266 STRONG_AUTH_TIMEOUT_ALARM_TAG, alarm, mHandler); 267 } 268 handleScheduleStrongAuthTimeout(int userId)269 private void handleScheduleStrongAuthTimeout(int userId) { 270 rescheduleStrongAuthTimeoutAlarm(mInjector.getElapsedRealtimeMs(), userId); 271 272 // cancel current non-strong biometric alarm listener for the user (if there was one) 273 cancelNonStrongBiometricAlarmListener(userId); 274 // cancel current non-strong biometric idle alarm listener for the user (if there was one) 275 cancelNonStrongBiometricIdleAlarmListener(userId); 276 // re-allow unlock with non-strong biometrics 277 setIsNonStrongBiometricAllowed(true, userId); 278 } 279 handleRefreshStrongAuthTimeout(int userId)280 private void handleRefreshStrongAuthTimeout(int userId) { 281 StrongAuthTimeoutAlarmListener alarm = mStrongAuthTimeoutAlarmListenerForUser.get(userId); 282 if (alarm != null) { 283 rescheduleStrongAuthTimeoutAlarm(alarm.getLatestStrongAuthTime(), userId); 284 } 285 } 286 handleScheduleNonStrongBiometricTimeout(int userId)287 private void handleScheduleNonStrongBiometricTimeout(int userId) { 288 if (DEBUG) Slog.d(TAG, "handleScheduleNonStrongBiometricTimeout for userId=" + userId); 289 long nextAlarmTime = mInjector.getNextAlarmTimeMs(DEFAULT_NON_STRONG_BIOMETRIC_TIMEOUT_MS); 290 NonStrongBiometricTimeoutAlarmListener alarm = mNonStrongBiometricTimeoutAlarmListener 291 .get(userId); 292 if (alarm != null) { 293 // Unlock with non-strong biometric will not affect the existing non-strong biometric 294 // timeout alarm 295 if (DEBUG) { 296 Slog.d(TAG, "There is an existing alarm for non-strong biometric" 297 + " fallback timeout, so do not re-schedule"); 298 } 299 } else { 300 if (DEBUG) { 301 Slog.d(TAG, "Schedule a new alarm for non-strong biometric fallback timeout"); 302 } 303 alarm = new NonStrongBiometricTimeoutAlarmListener(userId); 304 mNonStrongBiometricTimeoutAlarmListener.put(userId, alarm); 305 // schedule a new alarm listener for the user 306 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, nextAlarmTime, 307 NON_STRONG_BIOMETRIC_TIMEOUT_ALARM_TAG, alarm, mHandler); 308 } 309 310 // cancel current non-strong biometric idle alarm listener for the user (if there was one) 311 cancelNonStrongBiometricIdleAlarmListener(userId); 312 } 313 handleStrongBiometricUnlock(int userId)314 private void handleStrongBiometricUnlock(int userId) { 315 if (DEBUG) Slog.d(TAG, "handleStrongBiometricUnlock for userId=" + userId); 316 // cancel current non-strong biometric alarm listener for the user (if there was one) 317 cancelNonStrongBiometricAlarmListener(userId); 318 // cancel current non-strong biometric idle alarm listener for the user (if there was one) 319 cancelNonStrongBiometricIdleAlarmListener(userId); 320 // re-allow unlock with non-strong biometrics 321 setIsNonStrongBiometricAllowed(true, userId); 322 } 323 cancelNonStrongBiometricAlarmListener(int userId)324 private void cancelNonStrongBiometricAlarmListener(int userId) { 325 if (DEBUG) Slog.d(TAG, "cancelNonStrongBiometricAlarmListener for userId=" + userId); 326 NonStrongBiometricTimeoutAlarmListener alarm = mNonStrongBiometricTimeoutAlarmListener 327 .get(userId); 328 if (alarm != null) { 329 if (DEBUG) Slog.d(TAG, "Cancel alarm for non-strong biometric fallback timeout"); 330 mAlarmManager.cancel(alarm); 331 // need to remove the alarm when cancelled by primary auth or strong biometric 332 mNonStrongBiometricTimeoutAlarmListener.remove(userId); 333 } 334 } 335 cancelNonStrongBiometricIdleAlarmListener(int userId)336 private void cancelNonStrongBiometricIdleAlarmListener(int userId) { 337 if (DEBUG) Slog.d(TAG, "cancelNonStrongBiometricIdleAlarmListener for userId=" + userId); 338 // cancel idle alarm listener by any unlocks (i.e. primary auth, strong biometric, 339 // non-strong biometric) 340 NonStrongBiometricIdleTimeoutAlarmListener alarm = 341 mNonStrongBiometricIdleTimeoutAlarmListener.get(userId); 342 if (alarm != null) { 343 if (DEBUG) Slog.d(TAG, "Cancel alarm for non-strong biometric idle timeout"); 344 mAlarmManager.cancel(alarm); 345 } 346 } 347 348 @VisibleForTesting setIsNonStrongBiometricAllowed(boolean allowed, int userId)349 protected void setIsNonStrongBiometricAllowed(boolean allowed, int userId) { 350 if (DEBUG) { 351 Slog.d(TAG, "setIsNonStrongBiometricAllowed for allowed=" + allowed 352 + ", userId=" + userId); 353 } 354 if (userId == UserHandle.USER_ALL) { 355 for (int i = 0; i < mIsNonStrongBiometricAllowedForUser.size(); i++) { 356 int key = mIsNonStrongBiometricAllowedForUser.keyAt(i); 357 setIsNonStrongBiometricAllowedOneUser(allowed, key); 358 } 359 } else { 360 setIsNonStrongBiometricAllowedOneUser(allowed, userId); 361 } 362 } 363 setIsNonStrongBiometricAllowedOneUser(boolean allowed, int userId)364 private void setIsNonStrongBiometricAllowedOneUser(boolean allowed, int userId) { 365 if (DEBUG) { 366 Slog.d(TAG, "setIsNonStrongBiometricAllowedOneUser for allowed=" + allowed 367 + ", userId=" + userId); 368 } 369 boolean oldValue = mIsNonStrongBiometricAllowedForUser.get(userId, 370 mDefaultIsNonStrongBiometricAllowed); 371 if (allowed != oldValue) { 372 if (DEBUG) { 373 Slog.d(TAG, "mIsNonStrongBiometricAllowedForUser value changed:" 374 + " oldValue=" + oldValue + ", allowed=" + allowed); 375 } 376 mIsNonStrongBiometricAllowedForUser.put(userId, allowed); 377 notifyStrongAuthTrackersForIsNonStrongBiometricAllowed(allowed, userId); 378 } 379 } 380 handleScheduleNonStrongBiometricIdleTimeout(int userId)381 private void handleScheduleNonStrongBiometricIdleTimeout(int userId) { 382 if (DEBUG) Slog.d(TAG, "handleScheduleNonStrongBiometricIdleTimeout for userId=" + userId); 383 long nextAlarmTime = 384 mInjector.getNextAlarmTimeMs(DEFAULT_NON_STRONG_BIOMETRIC_IDLE_TIMEOUT_MS); 385 // cancel current alarm listener for the user (if there was one) 386 NonStrongBiometricIdleTimeoutAlarmListener alarm = 387 mNonStrongBiometricIdleTimeoutAlarmListener.get(userId); 388 if (alarm != null) { 389 if (DEBUG) Slog.d(TAG, "Cancel existing alarm for non-strong biometric idle timeout"); 390 mAlarmManager.cancel(alarm); 391 } else { 392 alarm = new NonStrongBiometricIdleTimeoutAlarmListener(userId); 393 mNonStrongBiometricIdleTimeoutAlarmListener.put(userId, alarm); 394 } 395 // schedule a new alarm listener for the user 396 if (DEBUG) Slog.d(TAG, "Schedule a new alarm for non-strong biometric idle timeout"); 397 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME, nextAlarmTime, 398 NON_STRONG_BIOMETRIC_IDLE_TIMEOUT_ALARM_TAG, alarm, mHandler); 399 } 400 notifyStrongAuthTrackers(int strongAuthReason, int userId)401 private void notifyStrongAuthTrackers(int strongAuthReason, int userId) { 402 int i = mTrackers.beginBroadcast(); 403 try { 404 while (i > 0) { 405 i--; 406 try { 407 mTrackers.getBroadcastItem(i).onStrongAuthRequiredChanged( 408 strongAuthReason, userId); 409 } catch (RemoteException e) { 410 Slog.e(TAG, "Exception while notifying StrongAuthTracker.", e); 411 } 412 } 413 } finally { 414 mTrackers.finishBroadcast(); 415 } 416 } 417 notifyStrongAuthTrackersForIsNonStrongBiometricAllowed(boolean allowed, int userId)418 private void notifyStrongAuthTrackersForIsNonStrongBiometricAllowed(boolean allowed, 419 int userId) { 420 if (DEBUG) { 421 Slog.d(TAG, "notifyStrongAuthTrackersForIsNonStrongBiometricAllowed" 422 + " for allowed=" + allowed + ", userId=" + userId); 423 } 424 int i = mTrackers.beginBroadcast(); 425 try { 426 while (i > 0) { 427 i--; 428 try { 429 mTrackers.getBroadcastItem(i).onIsNonStrongBiometricAllowedChanged( 430 allowed, userId); 431 } catch (RemoteException e) { 432 Slog.e(TAG, "Exception while notifying StrongAuthTracker: " 433 + "IsNonStrongBiometricAllowedChanged.", e); 434 } 435 } 436 } finally { 437 mTrackers.finishBroadcast(); 438 } 439 } 440 registerStrongAuthTracker(IStrongAuthTracker tracker)441 public void registerStrongAuthTracker(IStrongAuthTracker tracker) { 442 mHandler.obtainMessage(MSG_REGISTER_TRACKER, tracker).sendToTarget(); 443 } 444 unregisterStrongAuthTracker(IStrongAuthTracker tracker)445 public void unregisterStrongAuthTracker(IStrongAuthTracker tracker) { 446 mHandler.obtainMessage(MSG_UNREGISTER_TRACKER, tracker).sendToTarget(); 447 } 448 removeUser(int userId)449 public void removeUser(int userId) { 450 final int argNotUsed = 0; 451 mHandler.obtainMessage(MSG_REMOVE_USER, userId, argNotUsed).sendToTarget(); 452 } 453 requireStrongAuth(int strongAuthReason, int userId)454 public void requireStrongAuth(int strongAuthReason, int userId) { 455 if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_SYSTEM) { 456 mHandler.obtainMessage(MSG_REQUIRE_STRONG_AUTH, strongAuthReason, 457 userId).sendToTarget(); 458 } else { 459 throw new IllegalArgumentException( 460 "userId must be an explicit user id or USER_ALL"); 461 } 462 } 463 noLongerRequireStrongAuth(int strongAuthReason, int userId)464 void noLongerRequireStrongAuth(int strongAuthReason, int userId) { 465 if (userId == UserHandle.USER_ALL || userId >= UserHandle.USER_SYSTEM) { 466 mHandler.obtainMessage(MSG_NO_LONGER_REQUIRE_STRONG_AUTH, strongAuthReason, 467 userId).sendToTarget(); 468 } else { 469 throw new IllegalArgumentException( 470 "userId must be an explicit user id or USER_ALL"); 471 } 472 } 473 reportUnlock(int userId)474 public void reportUnlock(int userId) { 475 requireStrongAuth(STRONG_AUTH_NOT_REQUIRED, userId); 476 } 477 478 /** 479 * Report successful unlocking with primary auth 480 */ reportSuccessfulStrongAuthUnlock(int userId)481 public void reportSuccessfulStrongAuthUnlock(int userId) { 482 final int argNotUsed = 0; 483 mHandler.obtainMessage(MSG_SCHEDULE_STRONG_AUTH_TIMEOUT, userId, argNotUsed).sendToTarget(); 484 } 485 486 /** 487 * Refreshes pending strong auth timeout with the latest admin requirement set by device policy. 488 */ refreshStrongAuthTimeout(int userId)489 public void refreshStrongAuthTimeout(int userId) { 490 mHandler.obtainMessage(MSG_REFRESH_STRONG_AUTH_TIMEOUT, userId, 0).sendToTarget(); 491 } 492 493 /** 494 * Report successful unlocking with biometric 495 */ reportSuccessfulBiometricUnlock(boolean isStrongBiometric, int userId)496 public void reportSuccessfulBiometricUnlock(boolean isStrongBiometric, int userId) { 497 if (DEBUG) { 498 Slog.d(TAG, "reportSuccessfulBiometricUnlock for isStrongBiometric=" 499 + isStrongBiometric + ", userId=" + userId); 500 } 501 final int argNotUsed = 0; 502 if (isStrongBiometric) { // unlock with strong biometric 503 mHandler.obtainMessage(MSG_STRONG_BIOMETRIC_UNLOCK, userId, argNotUsed) 504 .sendToTarget(); 505 } else { // unlock with non-strong biometric (i.e. weak or convenience) 506 mHandler.obtainMessage(MSG_SCHEDULE_NON_STRONG_BIOMETRIC_TIMEOUT, userId, argNotUsed) 507 .sendToTarget(); 508 } 509 } 510 511 /** 512 * Schedule idle timeout for non-strong biometric (i.e. weak or convenience) 513 */ scheduleNonStrongBiometricIdleTimeout(int userId)514 public void scheduleNonStrongBiometricIdleTimeout(int userId) { 515 if (DEBUG) Slog.d(TAG, "scheduleNonStrongBiometricIdleTimeout for userId=" + userId); 516 final int argNotUsed = 0; 517 mHandler.obtainMessage(MSG_SCHEDULE_NON_STRONG_BIOMETRIC_IDLE_TIMEOUT, userId, argNotUsed) 518 .sendToTarget(); 519 } 520 521 /** 522 * Alarm of fallback timeout for primary auth 523 */ 524 @VisibleForTesting 525 protected class StrongAuthTimeoutAlarmListener implements OnAlarmListener { 526 527 private long mLatestStrongAuthTime; 528 private final int mUserId; 529 StrongAuthTimeoutAlarmListener(long latestStrongAuthTime, int userId)530 public StrongAuthTimeoutAlarmListener(long latestStrongAuthTime, int userId) { 531 mLatestStrongAuthTime = latestStrongAuthTime; 532 mUserId = userId; 533 } 534 535 /** 536 * Sets the most recent time when a successful strong auth happened, in number of 537 * milliseconds. 538 */ setLatestStrongAuthTime(long strongAuthTime)539 public void setLatestStrongAuthTime(long strongAuthTime) { 540 mLatestStrongAuthTime = strongAuthTime; 541 } 542 543 /** 544 * Returns the most recent time when a successful strong auth happened, in number of 545 * milliseconds. 546 */ getLatestStrongAuthTime()547 public long getLatestStrongAuthTime() { 548 return mLatestStrongAuthTime; 549 } 550 551 @Override onAlarm()552 public void onAlarm() { 553 requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_TIMEOUT, mUserId); 554 } 555 } 556 557 /** 558 * Alarm of fallback timeout for non-strong biometric (i.e. weak or convenience) 559 */ 560 @VisibleForTesting 561 protected class NonStrongBiometricTimeoutAlarmListener implements OnAlarmListener { 562 563 private final int mUserId; 564 NonStrongBiometricTimeoutAlarmListener(int userId)565 NonStrongBiometricTimeoutAlarmListener(int userId) { 566 mUserId = userId; 567 } 568 569 @Override onAlarm()570 public void onAlarm() { 571 requireStrongAuth(STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT, mUserId); 572 } 573 } 574 575 /** 576 * Alarm of idle timeout for non-strong biometric (i.e. weak or convenience biometric) 577 */ 578 @VisibleForTesting 579 protected class NonStrongBiometricIdleTimeoutAlarmListener implements OnAlarmListener { 580 581 private final int mUserId; 582 NonStrongBiometricIdleTimeoutAlarmListener(int userId)583 NonStrongBiometricIdleTimeoutAlarmListener(int userId) { 584 mUserId = userId; 585 } 586 587 @Override onAlarm()588 public void onAlarm() { 589 // disallow unlock with non-strong biometrics 590 setIsNonStrongBiometricAllowed(false, mUserId); 591 } 592 } 593 594 @VisibleForTesting 595 protected final Handler mHandler = new Handler(Looper.getMainLooper()) { 596 @Override 597 public void handleMessage(Message msg) { 598 switch (msg.what) { 599 case MSG_REGISTER_TRACKER: 600 handleAddStrongAuthTracker((IStrongAuthTracker) msg.obj); 601 break; 602 case MSG_UNREGISTER_TRACKER: 603 handleRemoveStrongAuthTracker((IStrongAuthTracker) msg.obj); 604 break; 605 case MSG_REQUIRE_STRONG_AUTH: 606 handleRequireStrongAuth(msg.arg1, msg.arg2); 607 break; 608 case MSG_REMOVE_USER: 609 handleRemoveUser(msg.arg1); 610 break; 611 case MSG_SCHEDULE_STRONG_AUTH_TIMEOUT: 612 handleScheduleStrongAuthTimeout(msg.arg1); 613 break; 614 case MSG_REFRESH_STRONG_AUTH_TIMEOUT: 615 handleRefreshStrongAuthTimeout(msg.arg1); 616 break; 617 case MSG_NO_LONGER_REQUIRE_STRONG_AUTH: 618 handleNoLongerRequireStrongAuth(msg.arg1, msg.arg2); 619 break; 620 case MSG_SCHEDULE_NON_STRONG_BIOMETRIC_TIMEOUT: 621 handleScheduleNonStrongBiometricTimeout(msg.arg1); 622 break; 623 case MSG_STRONG_BIOMETRIC_UNLOCK: 624 handleStrongBiometricUnlock(msg.arg1); 625 break; 626 case MSG_SCHEDULE_NON_STRONG_BIOMETRIC_IDLE_TIMEOUT: 627 handleScheduleNonStrongBiometricIdleTimeout(msg.arg1); 628 break; 629 } 630 } 631 }; 632 dump(IndentingPrintWriter pw)633 public void dump(IndentingPrintWriter pw) { 634 pw.println("PrimaryAuthFlags state:"); 635 pw.increaseIndent(); 636 for (int i = 0; i < mStrongAuthForUser.size(); i++) { 637 final int key = mStrongAuthForUser.keyAt(i); 638 final int value = mStrongAuthForUser.valueAt(i); 639 pw.println("userId=" + key + ", primaryAuthFlags=" + Integer.toHexString(value)); 640 } 641 pw.println(); 642 pw.decreaseIndent(); 643 644 pw.println("NonStrongBiometricAllowed state:"); 645 pw.increaseIndent(); 646 for (int i = 0; i < mIsNonStrongBiometricAllowedForUser.size(); i++) { 647 final int key = mIsNonStrongBiometricAllowedForUser.keyAt(i); 648 final boolean value = mIsNonStrongBiometricAllowedForUser.valueAt(i); 649 pw.println("userId=" + key + ", allowed=" + value); 650 } 651 pw.println(); 652 pw.decreaseIndent(); 653 } 654 } 655