• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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