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