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