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