1 /* 2 * Copyright (C) 2020 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.keyguard; 18 19 import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_BIOMETRIC; 20 import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_EXTENDED_ACCESS; 21 import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_NONE_SECURITY; 22 import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_PASSWORD; 23 import static com.android.keyguard.KeyguardSecurityContainer.BOUNCER_DISMISS_SIM; 24 import static com.android.keyguard.KeyguardSecurityContainer.USER_TYPE_PRIMARY; 25 import static com.android.keyguard.KeyguardSecurityContainer.USER_TYPE_SECONDARY_USER; 26 import static com.android.keyguard.KeyguardSecurityContainer.USER_TYPE_WORK_PROFILE; 27 import static com.android.systemui.DejankUtils.whitelistIpcs; 28 29 import android.app.admin.DevicePolicyManager; 30 import android.content.Intent; 31 import android.content.res.ColorStateList; 32 import android.content.res.Configuration; 33 import android.metrics.LogMaker; 34 import android.os.UserHandle; 35 import android.provider.Settings; 36 import android.util.Log; 37 import android.util.Slog; 38 import android.view.MotionEvent; 39 40 import com.android.internal.annotations.VisibleForTesting; 41 import com.android.internal.logging.MetricsLogger; 42 import com.android.internal.logging.UiEventLogger; 43 import com.android.internal.logging.nano.MetricsProto; 44 import com.android.internal.logging.nano.MetricsProto.MetricsEvent; 45 import com.android.internal.widget.LockPatternUtils; 46 import com.android.keyguard.KeyguardSecurityContainer.BouncerUiEvent; 47 import com.android.keyguard.KeyguardSecurityContainer.SecurityCallback; 48 import com.android.keyguard.KeyguardSecurityContainer.SwipeListener; 49 import com.android.keyguard.KeyguardSecurityModel.SecurityMode; 50 import com.android.keyguard.dagger.KeyguardBouncerScope; 51 import com.android.settingslib.utils.ThreadUtils; 52 import com.android.systemui.Gefingerpoken; 53 import com.android.systemui.R; 54 import com.android.systemui.classifier.FalsingCollector; 55 import com.android.systemui.shared.system.SysUiStatsLog; 56 import com.android.systemui.statusbar.policy.ConfigurationController; 57 import com.android.systemui.statusbar.policy.KeyguardStateController; 58 import com.android.systemui.util.ViewController; 59 60 import javax.inject.Inject; 61 62 /** Controller for {@link KeyguardSecurityContainer} */ 63 @KeyguardBouncerScope 64 public class KeyguardSecurityContainerController extends ViewController<KeyguardSecurityContainer> 65 implements KeyguardSecurityView { 66 67 private static final boolean DEBUG = KeyguardConstants.DEBUG; 68 private static final String TAG = "KeyguardSecurityView"; 69 70 private final AdminSecondaryLockScreenController mAdminSecondaryLockScreenController; 71 private final LockPatternUtils mLockPatternUtils; 72 private final KeyguardUpdateMonitor mUpdateMonitor; 73 private final KeyguardSecurityModel mSecurityModel; 74 private final MetricsLogger mMetricsLogger; 75 private final UiEventLogger mUiEventLogger; 76 private final KeyguardStateController mKeyguardStateController; 77 private final KeyguardSecurityViewFlipperController mSecurityViewFlipperController; 78 private final SecurityCallback mSecurityCallback; 79 private final ConfigurationController mConfigurationController; 80 private final FalsingCollector mFalsingCollector; 81 82 private int mLastOrientation = Configuration.ORIENTATION_UNDEFINED; 83 84 private SecurityMode mCurrentSecurityMode = SecurityMode.Invalid; 85 86 @VisibleForTesting 87 final Gefingerpoken mGlobalTouchListener = new Gefingerpoken() { 88 private MotionEvent mTouchDown; 89 @Override 90 public boolean onInterceptTouchEvent(MotionEvent ev) { 91 return false; 92 } 93 94 @Override 95 public boolean onTouchEvent(MotionEvent ev) { 96 // Do just a bit of our own falsing. People should only be tapping on the input, not 97 // swiping. 98 if (ev.getActionMasked() == MotionEvent.ACTION_DOWN) { 99 // If we're in one handed mode, the user can tap on the opposite side of the screen 100 // to move the bouncer across. In that case, inhibit the falsing (otherwise the taps 101 // to move the bouncer to each screen side can end up closing it instead). 102 if (mView.isOneHandedMode()) { 103 if ((mView.isOneHandedModeLeftAligned() && ev.getX() > mView.getWidth() / 2f) 104 || (!mView.isOneHandedModeLeftAligned() 105 && ev.getX() <= mView.getWidth() / 2f)) { 106 mFalsingCollector.avoidGesture(); 107 } 108 } 109 110 if (mTouchDown != null) { 111 mTouchDown.recycle(); 112 mTouchDown = null; 113 } 114 mTouchDown = MotionEvent.obtain(ev); 115 } else if (mTouchDown != null) { 116 if (ev.getActionMasked() == MotionEvent.ACTION_UP 117 || ev.getActionMasked() == MotionEvent.ACTION_CANCEL) { 118 mTouchDown.recycle(); 119 mTouchDown = null; 120 } 121 } 122 return false; 123 } 124 }; 125 126 private KeyguardSecurityCallback mKeyguardSecurityCallback = new KeyguardSecurityCallback() { 127 public void userActivity() { 128 if (mSecurityCallback != null) { 129 mSecurityCallback.userActivity(); 130 } 131 } 132 133 @Override 134 public void onUserInput() { 135 mUpdateMonitor.cancelFaceAuth(); 136 } 137 138 @Override 139 public void dismiss(boolean authenticated, int targetId) { 140 dismiss(authenticated, targetId, /* bypassSecondaryLockScreen */ false); 141 } 142 143 @Override 144 public void dismiss(boolean authenticated, int targetId, 145 boolean bypassSecondaryLockScreen) { 146 mSecurityCallback.dismiss(authenticated, targetId, bypassSecondaryLockScreen); 147 } 148 149 public boolean isVerifyUnlockOnly() { 150 return false; 151 } 152 153 public void reportUnlockAttempt(int userId, boolean success, int timeoutMs) { 154 int bouncerSide = SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__SIDE__DEFAULT; 155 if (canUseOneHandedBouncer()) { 156 bouncerSide = isOneHandedKeyguardLeftAligned() 157 ? SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__SIDE__LEFT 158 : SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__SIDE__RIGHT; 159 } 160 161 if (success) { 162 SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED, 163 SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__RESULT__SUCCESS, 164 bouncerSide); 165 mLockPatternUtils.reportSuccessfulPasswordAttempt(userId); 166 // Force a garbage collection in an attempt to erase any lockscreen password left in 167 // memory. Do it asynchronously with a 5-sec delay to avoid making the keyguard 168 // dismiss animation janky. 169 ThreadUtils.postOnBackgroundThread(() -> { 170 try { 171 Thread.sleep(5000); 172 } catch (InterruptedException ignored) { } 173 System.gc(); 174 System.runFinalization(); 175 System.gc(); 176 }); 177 } else { 178 SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED, 179 SysUiStatsLog.KEYGUARD_BOUNCER_PASSWORD_ENTERED__RESULT__FAILURE, 180 bouncerSide); 181 reportFailedUnlockAttempt(userId, timeoutMs); 182 } 183 mMetricsLogger.write(new LogMaker(MetricsEvent.BOUNCER) 184 .setType(success ? MetricsEvent.TYPE_SUCCESS : MetricsEvent.TYPE_FAILURE)); 185 mUiEventLogger.log(success ? BouncerUiEvent.BOUNCER_PASSWORD_SUCCESS 186 : BouncerUiEvent.BOUNCER_PASSWORD_FAILURE); 187 } 188 189 public void reset() { 190 mSecurityCallback.reset(); 191 } 192 193 public void onCancelClicked() { 194 mSecurityCallback.onCancelClicked(); 195 } 196 }; 197 198 199 private SwipeListener mSwipeListener = new SwipeListener() { 200 @Override 201 public void onSwipeUp() { 202 if (!mUpdateMonitor.isFaceDetectionRunning()) { 203 mUpdateMonitor.requestFaceAuth(true); 204 mKeyguardSecurityCallback.userActivity(); 205 showMessage(null, null); 206 } 207 } 208 }; 209 private ConfigurationController.ConfigurationListener mConfigurationListener = 210 new ConfigurationController.ConfigurationListener() { 211 @Override 212 public void onThemeChanged() { 213 mSecurityViewFlipperController.reloadColors(); 214 } 215 216 @Override 217 public void onUiModeChanged() { 218 mSecurityViewFlipperController.reloadColors(); 219 } 220 }; 221 KeyguardSecurityContainerController(KeyguardSecurityContainer view, AdminSecondaryLockScreenController.Factory adminSecondaryLockScreenControllerFactory, LockPatternUtils lockPatternUtils, KeyguardUpdateMonitor keyguardUpdateMonitor, KeyguardSecurityModel keyguardSecurityModel, MetricsLogger metricsLogger, UiEventLogger uiEventLogger, KeyguardStateController keyguardStateController, SecurityCallback securityCallback, KeyguardSecurityViewFlipperController securityViewFlipperController, ConfigurationController configurationController, FalsingCollector falsingCollector)222 private KeyguardSecurityContainerController(KeyguardSecurityContainer view, 223 AdminSecondaryLockScreenController.Factory adminSecondaryLockScreenControllerFactory, 224 LockPatternUtils lockPatternUtils, 225 KeyguardUpdateMonitor keyguardUpdateMonitor, 226 KeyguardSecurityModel keyguardSecurityModel, 227 MetricsLogger metricsLogger, 228 UiEventLogger uiEventLogger, 229 KeyguardStateController keyguardStateController, 230 SecurityCallback securityCallback, 231 KeyguardSecurityViewFlipperController securityViewFlipperController, 232 ConfigurationController configurationController, 233 FalsingCollector falsingCollector) { 234 super(view); 235 mLockPatternUtils = lockPatternUtils; 236 mUpdateMonitor = keyguardUpdateMonitor; 237 mSecurityModel = keyguardSecurityModel; 238 mMetricsLogger = metricsLogger; 239 mUiEventLogger = uiEventLogger; 240 mKeyguardStateController = keyguardStateController; 241 mSecurityCallback = securityCallback; 242 mSecurityViewFlipperController = securityViewFlipperController; 243 mAdminSecondaryLockScreenController = adminSecondaryLockScreenControllerFactory.create( 244 mKeyguardSecurityCallback); 245 mConfigurationController = configurationController; 246 mLastOrientation = getResources().getConfiguration().orientation; 247 mFalsingCollector = falsingCollector; 248 } 249 250 @Override onInit()251 public void onInit() { 252 mSecurityViewFlipperController.init(); 253 } 254 255 @Override onViewAttached()256 protected void onViewAttached() { 257 mView.setSwipeListener(mSwipeListener); 258 mView.addMotionEventListener(mGlobalTouchListener); 259 mConfigurationController.addCallback(mConfigurationListener); 260 } 261 262 @Override onViewDetached()263 protected void onViewDetached() { 264 mConfigurationController.removeCallback(mConfigurationListener); 265 mView.removeMotionEventListener(mGlobalTouchListener); 266 } 267 268 /** */ onPause()269 public void onPause() { 270 mAdminSecondaryLockScreenController.hide(); 271 if (mCurrentSecurityMode != SecurityMode.None) { 272 getCurrentSecurityController().onPause(); 273 } 274 mView.onPause(); 275 } 276 277 278 /** 279 * Shows the primary security screen for the user. This will be either the multi-selector 280 * or the user's security method. 281 * @param turningOff true if the device is being turned off 282 */ showPrimarySecurityScreen(boolean turningOff)283 public void showPrimarySecurityScreen(boolean turningOff) { 284 SecurityMode securityMode = whitelistIpcs(() -> mSecurityModel.getSecurityMode( 285 KeyguardUpdateMonitor.getCurrentUser())); 286 if (DEBUG) Log.v(TAG, "showPrimarySecurityScreen(turningOff=" + turningOff + ")"); 287 showSecurityScreen(securityMode); 288 } 289 290 @Override showPromptReason(int reason)291 public void showPromptReason(int reason) { 292 if (mCurrentSecurityMode != SecurityMode.None) { 293 if (reason != PROMPT_REASON_NONE) { 294 Log.i(TAG, "Strong auth required, reason: " + reason); 295 } 296 getCurrentSecurityController().showPromptReason(reason); 297 } 298 } 299 showMessage(CharSequence message, ColorStateList colorState)300 public void showMessage(CharSequence message, ColorStateList colorState) { 301 if (mCurrentSecurityMode != SecurityMode.None) { 302 getCurrentSecurityController().showMessage(message, colorState); 303 } 304 } 305 getCurrentSecurityMode()306 public SecurityMode getCurrentSecurityMode() { 307 return mCurrentSecurityMode; 308 } 309 dismiss(boolean authenticated, int targetUserId)310 public void dismiss(boolean authenticated, int targetUserId) { 311 mKeyguardSecurityCallback.dismiss(authenticated, targetUserId); 312 } 313 reset()314 public void reset() { 315 mView.reset(); 316 mSecurityViewFlipperController.reset(); 317 } 318 getTitle()319 public CharSequence getTitle() { 320 return mView.getTitle(); 321 } 322 323 @Override onResume(int reason)324 public void onResume(int reason) { 325 if (mCurrentSecurityMode != SecurityMode.None) { 326 int state = SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN; 327 if (canUseOneHandedBouncer()) { 328 state = mView.isOneHandedModeLeftAligned() 329 ? SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN_LEFT 330 : SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED__STATE__SHOWN_RIGHT; 331 } 332 SysUiStatsLog.write(SysUiStatsLog.KEYGUARD_BOUNCER_STATE_CHANGED, state); 333 334 getCurrentSecurityController().onResume(reason); 335 } 336 mView.onResume( 337 mSecurityModel.getSecurityMode(KeyguardUpdateMonitor.getCurrentUser()), 338 mKeyguardStateController.isFaceAuthEnabled()); 339 } 340 startAppearAnimation()341 public void startAppearAnimation() { 342 if (mCurrentSecurityMode != SecurityMode.None) { 343 getCurrentSecurityController().startAppearAnimation(); 344 } 345 } 346 startDisappearAnimation(Runnable onFinishRunnable)347 public boolean startDisappearAnimation(Runnable onFinishRunnable) { 348 mView.startDisappearAnimation(getCurrentSecurityMode()); 349 350 if (mCurrentSecurityMode != SecurityMode.None) { 351 return getCurrentSecurityController().startDisappearAnimation(onFinishRunnable); 352 } 353 354 return false; 355 } 356 onStartingToHide()357 public void onStartingToHide() { 358 if (mCurrentSecurityMode != SecurityMode.None) { 359 getCurrentSecurityController().onStartingToHide(); 360 } 361 } 362 363 /** 364 * Shows the next security screen if there is one. 365 * @param authenticated true if the user entered the correct authentication 366 * @param targetUserId a user that needs to be the foreground user at the finish (if called) 367 * completion. 368 * @param bypassSecondaryLockScreen true if the user is allowed to bypass the secondary 369 * secondary lock screen requirement, if any. 370 * @return true if keyguard is done 371 */ showNextSecurityScreenOrFinish(boolean authenticated, int targetUserId, boolean bypassSecondaryLockScreen)372 public boolean showNextSecurityScreenOrFinish(boolean authenticated, int targetUserId, 373 boolean bypassSecondaryLockScreen) { 374 375 if (DEBUG) Log.d(TAG, "showNextSecurityScreenOrFinish(" + authenticated + ")"); 376 boolean finish = false; 377 boolean strongAuth = false; 378 int eventSubtype = -1; 379 BouncerUiEvent uiEvent = BouncerUiEvent.UNKNOWN; 380 if (mUpdateMonitor.getUserHasTrust(targetUserId)) { 381 finish = true; 382 eventSubtype = BOUNCER_DISMISS_EXTENDED_ACCESS; 383 uiEvent = BouncerUiEvent.BOUNCER_DISMISS_EXTENDED_ACCESS; 384 } else if (mUpdateMonitor.getUserUnlockedWithBiometric(targetUserId)) { 385 finish = true; 386 eventSubtype = BOUNCER_DISMISS_BIOMETRIC; 387 uiEvent = BouncerUiEvent.BOUNCER_DISMISS_BIOMETRIC; 388 } else if (SecurityMode.None == getCurrentSecurityMode()) { 389 SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId); 390 if (SecurityMode.None == securityMode) { 391 finish = true; // no security required 392 eventSubtype = BOUNCER_DISMISS_NONE_SECURITY; 393 uiEvent = BouncerUiEvent.BOUNCER_DISMISS_NONE_SECURITY; 394 } else { 395 showSecurityScreen(securityMode); // switch to the alternate security view 396 } 397 } else if (authenticated) { 398 switch (getCurrentSecurityMode()) { 399 case Pattern: 400 case Password: 401 case PIN: 402 strongAuth = true; 403 finish = true; 404 eventSubtype = BOUNCER_DISMISS_PASSWORD; 405 uiEvent = BouncerUiEvent.BOUNCER_DISMISS_PASSWORD; 406 break; 407 408 case SimPin: 409 case SimPuk: 410 // Shortcut for SIM PIN/PUK to go to directly to user's security screen or home 411 SecurityMode securityMode = mSecurityModel.getSecurityMode(targetUserId); 412 if (securityMode == SecurityMode.None && mLockPatternUtils.isLockScreenDisabled( 413 KeyguardUpdateMonitor.getCurrentUser())) { 414 finish = true; 415 eventSubtype = BOUNCER_DISMISS_SIM; 416 uiEvent = BouncerUiEvent.BOUNCER_DISMISS_SIM; 417 } else { 418 showSecurityScreen(securityMode); 419 } 420 break; 421 422 default: 423 Log.v(TAG, "Bad security screen " + getCurrentSecurityMode() 424 + ", fail safe"); 425 showPrimarySecurityScreen(false); 426 break; 427 } 428 } 429 // Check for device admin specified additional security measures. 430 if (finish && !bypassSecondaryLockScreen) { 431 Intent secondaryLockscreenIntent = 432 mUpdateMonitor.getSecondaryLockscreenRequirement(targetUserId); 433 if (secondaryLockscreenIntent != null) { 434 mAdminSecondaryLockScreenController.show(secondaryLockscreenIntent); 435 return false; 436 } 437 } 438 if (eventSubtype != -1) { 439 mMetricsLogger.write(new LogMaker(MetricsProto.MetricsEvent.BOUNCER) 440 .setType(MetricsProto.MetricsEvent.TYPE_DISMISS).setSubtype(eventSubtype)); 441 } 442 if (uiEvent != BouncerUiEvent.UNKNOWN) { 443 mUiEventLogger.log(uiEvent); 444 } 445 if (finish) { 446 mSecurityCallback.finish(strongAuth, targetUserId); 447 } 448 return finish; 449 } 450 needsInput()451 public boolean needsInput() { 452 return getCurrentSecurityController().needsInput(); 453 } 454 455 /** 456 * Switches to the given security view unless it's already being shown, in which case 457 * this is a no-op. 458 * 459 * @param securityMode 460 */ 461 @VisibleForTesting showSecurityScreen(SecurityMode securityMode)462 void showSecurityScreen(SecurityMode securityMode) { 463 if (DEBUG) Log.d(TAG, "showSecurityScreen(" + securityMode + ")"); 464 465 if (securityMode == SecurityMode.Invalid || securityMode == mCurrentSecurityMode) { 466 return; 467 } 468 469 KeyguardInputViewController<KeyguardInputView> oldView = getCurrentSecurityController(); 470 471 // Emulate Activity life cycle 472 if (oldView != null) { 473 oldView.onPause(); 474 } 475 476 KeyguardInputViewController<KeyguardInputView> newView = changeSecurityMode(securityMode); 477 if (newView != null) { 478 newView.onResume(KeyguardSecurityView.VIEW_REVEALED); 479 mSecurityViewFlipperController.show(newView); 480 configureOneHandedMode(); 481 } 482 483 mSecurityCallback.onSecurityModeChanged( 484 securityMode, newView != null && newView.needsInput()); 485 } 486 487 /** Read whether the one-handed keyguard should be on the left/right from settings. */ isOneHandedKeyguardLeftAligned()488 private boolean isOneHandedKeyguardLeftAligned() { 489 try { 490 return Settings.Global.getInt(mView.getContext().getContentResolver(), 491 Settings.Global.ONE_HANDED_KEYGUARD_SIDE) 492 == Settings.Global.ONE_HANDED_KEYGUARD_SIDE_LEFT; 493 } catch (Settings.SettingNotFoundException ex) { 494 return true; 495 } 496 } 497 canUseOneHandedBouncer()498 private boolean canUseOneHandedBouncer() { 499 // Is it enabled? 500 if (!getResources().getBoolean( 501 com.android.internal.R.bool.config_enableDynamicKeyguardPositioning)) { 502 return false; 503 } 504 505 if (!KeyguardSecurityModel.isSecurityViewOneHanded(mCurrentSecurityMode)) { 506 return false; 507 } 508 509 return getResources().getBoolean(R.bool.can_use_one_handed_bouncer); 510 } 511 configureOneHandedMode()512 private void configureOneHandedMode() { 513 boolean oneHandedMode = canUseOneHandedBouncer(); 514 515 mView.setOneHandedMode(oneHandedMode); 516 517 if (oneHandedMode) { 518 mView.setOneHandedModeLeftAligned( 519 isOneHandedKeyguardLeftAligned(), /* animate= */false); 520 } 521 } 522 reportFailedUnlockAttempt(int userId, int timeoutMs)523 public void reportFailedUnlockAttempt(int userId, int timeoutMs) { 524 // +1 for this time 525 final int failedAttempts = mLockPatternUtils.getCurrentFailedPasswordAttempts(userId) + 1; 526 527 if (DEBUG) Log.d(TAG, "reportFailedPatternAttempt: #" + failedAttempts); 528 529 final DevicePolicyManager dpm = mLockPatternUtils.getDevicePolicyManager(); 530 final int failedAttemptsBeforeWipe = 531 dpm.getMaximumFailedPasswordsForWipe(null, userId); 532 533 final int remainingBeforeWipe = failedAttemptsBeforeWipe > 0 534 ? (failedAttemptsBeforeWipe - failedAttempts) 535 : Integer.MAX_VALUE; // because DPM returns 0 if no restriction 536 if (remainingBeforeWipe < LockPatternUtils.FAILED_ATTEMPTS_BEFORE_WIPE_GRACE) { 537 // The user has installed a DevicePolicyManager that requests a user/profile to be wiped 538 // N attempts. Once we get below the grace period, we post this dialog every time as a 539 // clear warning until the deletion fires. 540 // Check which profile has the strictest policy for failed password attempts 541 final int expiringUser = dpm.getProfileWithMinimumFailedPasswordsForWipe(userId); 542 int userType = USER_TYPE_PRIMARY; 543 if (expiringUser == userId) { 544 // TODO: http://b/23522538 545 if (expiringUser != UserHandle.USER_SYSTEM) { 546 userType = USER_TYPE_SECONDARY_USER; 547 } 548 } else if (expiringUser != UserHandle.USER_NULL) { 549 userType = USER_TYPE_WORK_PROFILE; 550 } // If USER_NULL, which shouldn't happen, leave it as USER_TYPE_PRIMARY 551 if (remainingBeforeWipe > 0) { 552 mView.showAlmostAtWipeDialog(failedAttempts, remainingBeforeWipe, userType); 553 } else { 554 // Too many attempts. The device will be wiped shortly. 555 Slog.i(TAG, "Too many unlock attempts; user " + expiringUser + " will be wiped!"); 556 mView.showWipeDialog(failedAttempts, userType); 557 } 558 } 559 mLockPatternUtils.reportFailedPasswordAttempt(userId); 560 if (timeoutMs > 0) { 561 mLockPatternUtils.reportPasswordLockout(timeoutMs, userId); 562 mView.showTimeoutDialog(userId, timeoutMs, mLockPatternUtils, 563 mSecurityModel.getSecurityMode(userId)); 564 } 565 } 566 getCurrentSecurityController()567 private KeyguardInputViewController<KeyguardInputView> getCurrentSecurityController() { 568 return mSecurityViewFlipperController 569 .getSecurityView(mCurrentSecurityMode, mKeyguardSecurityCallback); 570 } 571 changeSecurityMode( SecurityMode securityMode)572 private KeyguardInputViewController<KeyguardInputView> changeSecurityMode( 573 SecurityMode securityMode) { 574 mCurrentSecurityMode = securityMode; 575 return getCurrentSecurityController(); 576 } 577 578 /** 579 * Apply keyguard configuration from the currently active resources. This can be called when the 580 * device configuration changes, to re-apply some resources that are qualified on the device 581 * configuration. 582 */ updateResources()583 public void updateResources() { 584 int newOrientation = getResources().getConfiguration().orientation; 585 if (newOrientation != mLastOrientation) { 586 mLastOrientation = newOrientation; 587 configureOneHandedMode(); 588 } 589 } 590 591 /** Update keyguard position based on a tapped X coordinate. */ updateKeyguardPosition(float x)592 public void updateKeyguardPosition(float x) { 593 if (mView.isOneHandedMode()) { 594 mView.setOneHandedModeLeftAligned(x <= mView.getWidth() / 2f, false); 595 } 596 } 597 598 static class Factory { 599 600 private final KeyguardSecurityContainer mView; 601 private final AdminSecondaryLockScreenController.Factory 602 mAdminSecondaryLockScreenControllerFactory; 603 private final LockPatternUtils mLockPatternUtils; 604 private final KeyguardUpdateMonitor mKeyguardUpdateMonitor; 605 private final KeyguardSecurityModel mKeyguardSecurityModel; 606 private final MetricsLogger mMetricsLogger; 607 private final UiEventLogger mUiEventLogger; 608 private final KeyguardStateController mKeyguardStateController; 609 private final KeyguardSecurityViewFlipperController mSecurityViewFlipperController; 610 private final ConfigurationController mConfigurationController; 611 private final FalsingCollector mFalsingCollector; 612 613 @Inject Factory(KeyguardSecurityContainer view, AdminSecondaryLockScreenController.Factory adminSecondaryLockScreenControllerFactory, LockPatternUtils lockPatternUtils, KeyguardUpdateMonitor keyguardUpdateMonitor, KeyguardSecurityModel keyguardSecurityModel, MetricsLogger metricsLogger, UiEventLogger uiEventLogger, KeyguardStateController keyguardStateController, KeyguardSecurityViewFlipperController securityViewFlipperController, ConfigurationController configurationController, FalsingCollector falsingCollector)614 Factory(KeyguardSecurityContainer view, 615 AdminSecondaryLockScreenController.Factory 616 adminSecondaryLockScreenControllerFactory, 617 LockPatternUtils lockPatternUtils, 618 KeyguardUpdateMonitor keyguardUpdateMonitor, 619 KeyguardSecurityModel keyguardSecurityModel, 620 MetricsLogger metricsLogger, 621 UiEventLogger uiEventLogger, 622 KeyguardStateController keyguardStateController, 623 KeyguardSecurityViewFlipperController securityViewFlipperController, 624 ConfigurationController configurationController, 625 FalsingCollector falsingCollector) { 626 mView = view; 627 mAdminSecondaryLockScreenControllerFactory = adminSecondaryLockScreenControllerFactory; 628 mLockPatternUtils = lockPatternUtils; 629 mKeyguardUpdateMonitor = keyguardUpdateMonitor; 630 mKeyguardSecurityModel = keyguardSecurityModel; 631 mMetricsLogger = metricsLogger; 632 mUiEventLogger = uiEventLogger; 633 mKeyguardStateController = keyguardStateController; 634 mSecurityViewFlipperController = securityViewFlipperController; 635 mConfigurationController = configurationController; 636 mFalsingCollector = falsingCollector; 637 } 638 create( SecurityCallback securityCallback)639 public KeyguardSecurityContainerController create( 640 SecurityCallback securityCallback) { 641 return new KeyguardSecurityContainerController(mView, 642 mAdminSecondaryLockScreenControllerFactory, mLockPatternUtils, 643 mKeyguardUpdateMonitor, mKeyguardSecurityModel, mMetricsLogger, mUiEventLogger, 644 mKeyguardStateController, securityCallback, mSecurityViewFlipperController, 645 mConfigurationController, mFalsingCollector); 646 } 647 648 } 649 } 650