1 /*
2  * Copyright (C) 2019 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.systemui.keyguard;
18 
19 import static android.provider.Settings.Secure.LOCK_SCREEN_LOCK_AFTER_TIMEOUT;
20 import static android.view.WindowManager.TRANSIT_OLD_KEYGUARD_GOING_AWAY;
21 import static android.view.WindowManagerPolicyConstants.OFF_BECAUSE_OF_TIMEOUT;
22 import static android.view.WindowManagerPolicyConstants.OFF_BECAUSE_OF_USER;
23 
24 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST;
25 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW;
26 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT;
27 import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN;
28 import static com.android.systemui.Flags.FLAG_KEYGUARD_WM_STATE_REFACTOR;
29 import static com.android.systemui.Flags.FLAG_REFACTOR_GET_CURRENT_USER;
30 import static com.android.systemui.keyguard.KeyguardViewMediator.DELAYED_KEYGUARD_ACTION;
31 import static com.android.systemui.keyguard.KeyguardViewMediator.KEYGUARD_LOCK_AFTER_DELAY_DEFAULT;
32 import static com.android.systemui.keyguard.KeyguardViewMediator.REBOOT_MAINLINE_UPDATE;
33 import static com.android.systemui.keyguard.KeyguardViewMediator.SYS_BOOT_REASON_PROP;
34 
35 import static org.junit.Assert.assertEquals;
36 import static org.junit.Assert.assertFalse;
37 import static org.junit.Assert.assertTrue;
38 import static org.junit.Assert.fail;
39 import static org.mockito.ArgumentMatchers.any;
40 import static org.mockito.ArgumentMatchers.anyBoolean;
41 import static org.mockito.ArgumentMatchers.anyInt;
42 import static org.mockito.ArgumentMatchers.anyLong;
43 import static org.mockito.ArgumentMatchers.anyString;
44 import static org.mockito.Mockito.atLeast;
45 import static org.mockito.Mockito.atLeastOnce;
46 import static org.mockito.Mockito.clearInvocations;
47 import static org.mockito.Mockito.doAnswer;
48 import static org.mockito.Mockito.eq;
49 import static org.mockito.Mockito.inOrder;
50 import static org.mockito.Mockito.mock;
51 import static org.mockito.Mockito.never;
52 import static org.mockito.Mockito.reset;
53 import static org.mockito.Mockito.verify;
54 import static org.mockito.Mockito.when;
55 
56 import android.app.AlarmManager;
57 import android.app.IActivityManager;
58 import android.app.IActivityTaskManager;
59 import android.app.PendingIntent;
60 import android.app.admin.DevicePolicyManager;
61 import android.app.trust.TrustManager;
62 import android.content.Context;
63 import android.os.PowerManager;
64 import android.os.PowerManager.WakeLock;
65 import android.os.RemoteException;
66 import android.telephony.TelephonyManager;
67 import android.testing.AndroidTestingRunner;
68 import android.testing.TestableLooper;
69 import android.view.IRemoteAnimationFinishedCallback;
70 import android.view.RemoteAnimationTarget;
71 import android.view.View;
72 import android.view.ViewRootImpl;
73 import android.view.WindowManager;
74 
75 import androidx.test.filters.SmallTest;
76 
77 import com.android.internal.foldables.FoldGracePeriodProvider;
78 import com.android.internal.logging.InstanceId;
79 import com.android.internal.logging.UiEventLogger;
80 import com.android.internal.widget.LockPatternUtils;
81 import com.android.keyguard.KeyguardDisplayManager;
82 import com.android.keyguard.KeyguardSecurityView;
83 import com.android.keyguard.KeyguardUpdateMonitor;
84 import com.android.keyguard.KeyguardUpdateMonitorCallback;
85 import com.android.keyguard.TestScopeProvider;
86 import com.android.keyguard.mediator.ScreenOnCoordinator;
87 import com.android.systemui.DejankUtils;
88 import com.android.systemui.SysuiTestCase;
89 import com.android.systemui.animation.ActivityTransitionAnimator;
90 import com.android.systemui.biometrics.AuthController;
91 import com.android.systemui.broadcast.BroadcastDispatcher;
92 import com.android.systemui.classifier.FalsingCollectorFake;
93 import com.android.systemui.colorextraction.SysuiColorExtractor;
94 import com.android.systemui.communal.ui.viewmodel.CommunalTransitionViewModel;
95 import com.android.systemui.dreams.DreamOverlayStateController;
96 import com.android.systemui.dreams.ui.viewmodel.DreamViewModel;
97 import com.android.systemui.dump.DumpManager;
98 import com.android.systemui.flags.FakeFeatureFlags;
99 import com.android.systemui.flags.SystemPropertiesHelper;
100 import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor;
101 import com.android.systemui.kosmos.KosmosJavaAdapter;
102 import com.android.systemui.log.SessionTracker;
103 import com.android.systemui.navigationbar.NavigationModeController;
104 import com.android.systemui.scene.FakeWindowRootViewComponent;
105 import com.android.systemui.scene.ui.view.WindowRootView;
106 import com.android.systemui.settings.UserTracker;
107 import com.android.systemui.shade.NotificationShadeWindowControllerImpl;
108 import com.android.systemui.shade.ShadeController;
109 import com.android.systemui.shade.ShadeExpansionStateManager;
110 import com.android.systemui.shade.ShadeWindowLogger;
111 import com.android.systemui.shade.domain.interactor.ShadeInteractor;
112 import com.android.systemui.statusbar.NotificationShadeDepthController;
113 import com.android.systemui.statusbar.NotificationShadeWindowController;
114 import com.android.systemui.statusbar.SysuiStatusBarStateController;
115 import com.android.systemui.statusbar.phone.BiometricUnlockController;
116 import com.android.systemui.statusbar.phone.CentralSurfaces;
117 import com.android.systemui.statusbar.phone.DozeParameters;
118 import com.android.systemui.statusbar.phone.KeyguardBypassController;
119 import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
120 import com.android.systemui.statusbar.phone.ScrimController;
121 import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
122 import com.android.systemui.statusbar.policy.ConfigurationController;
123 import com.android.systemui.statusbar.policy.KeyguardStateController;
124 import com.android.systemui.statusbar.policy.UserSwitcherController;
125 import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
126 import com.android.systemui.util.DeviceConfigProxy;
127 import com.android.systemui.util.DeviceConfigProxyFake;
128 import com.android.systemui.util.concurrency.FakeExecutor;
129 import com.android.systemui.util.kotlin.JavaAdapter;
130 import com.android.systemui.util.settings.SecureSettings;
131 import com.android.systemui.util.settings.SystemSettings;
132 import com.android.systemui.util.time.FakeSystemClock;
133 import com.android.systemui.wallpapers.data.repository.FakeWallpaperRepository;
134 import com.android.wm.shell.keyguard.KeyguardTransitions;
135 
136 import kotlinx.coroutines.CoroutineDispatcher;
137 import kotlinx.coroutines.flow.Flow;
138 import kotlinx.coroutines.test.TestScope;
139 
140 import org.junit.After;
141 import org.junit.Before;
142 import org.junit.Test;
143 import org.junit.runner.RunWith;
144 import org.mockito.ArgumentCaptor;
145 import org.mockito.Captor;
146 import org.mockito.InOrder;
147 import org.mockito.Mock;
148 import org.mockito.MockitoAnnotations;
149 
150 @RunWith(AndroidTestingRunner.class)
151 @TestableLooper.RunWithLooper
152 @SmallTest
153 public class KeyguardViewMediatorTest extends SysuiTestCase {
154     private final KosmosJavaAdapter mKosmos = new KosmosJavaAdapter(this);
155     private KeyguardViewMediator mViewMediator;
156 
157     private final TestScope mTestScope = TestScopeProvider.getTestScope();
158     private final JavaAdapter mJavaAdapter = new JavaAdapter(mTestScope.getBackgroundScope());
159 
160     private @Mock UserTracker mUserTracker;
161     private @Mock DevicePolicyManager mDevicePolicyManager;
162     private @Mock LockPatternUtils mLockPatternUtils;
163     private @Mock KeyguardUpdateMonitor mUpdateMonitor;
164     private @Mock StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
165     private @Mock BroadcastDispatcher mBroadcastDispatcher;
166     private @Mock DismissCallbackRegistry mDismissCallbackRegistry;
167     private @Mock DumpManager mDumpManager;
168     private @Mock WindowManager mWindowManager;
169     private @Mock IActivityManager mActivityManager;
170     private @Mock ConfigurationController mConfigurationController;
171     private @Mock PowerManager mPowerManager;
172     private @Mock TrustManager mTrustManager;
173     private @Mock UserSwitcherController mUserSwitcherController;
174     private @Mock NavigationModeController mNavigationModeController;
175     private @Mock KeyguardDisplayManager mKeyguardDisplayManager;
176     private @Mock KeyguardBypassController mKeyguardBypassController;
177     private @Mock DozeParameters mDozeParameters;
178     private @Mock SysuiStatusBarStateController mStatusBarStateController;
179     private @Mock KeyguardStateController mKeyguardStateController;
180     private @Mock NotificationShadeDepthController mNotificationShadeDepthController;
181     private @Mock KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
182     private @Mock ScreenOffAnimationController mScreenOffAnimationController;
183     private @Mock ScreenOnCoordinator mScreenOnCoordinator;
184     private @Mock KeyguardTransitions mKeyguardTransitions;
185     private @Mock ShadeController mShadeController;
186     private NotificationShadeWindowController mNotificationShadeWindowController;
187     private @Mock DreamOverlayStateController mDreamOverlayStateController;
188     private @Mock ActivityTransitionAnimator mActivityTransitionAnimator;
189     private @Mock ScrimController mScrimController;
190     private @Mock IActivityTaskManager mActivityTaskManagerService;
191     private @Mock SysuiColorExtractor mColorExtractor;
192     private @Mock AuthController mAuthController;
193     private @Mock ShadeExpansionStateManager mShadeExpansionStateManager;
194     private @Mock ShadeInteractor mShadeInteractor;
195     private @Mock ShadeWindowLogger mShadeWindowLogger;
196     private @Mock SelectedUserInteractor mSelectedUserInteractor;
197     private @Mock KeyguardInteractor mKeyguardInteractor;
198     private @Captor ArgumentCaptor<KeyguardStateController.Callback>
199             mKeyguardStateControllerCallback;
200     private @Captor ArgumentCaptor<KeyguardUpdateMonitorCallback>
201             mKeyguardUpdateMonitorCallbackCaptor;
202     private DeviceConfigProxy mDeviceConfig = new DeviceConfigProxyFake();
203     private FakeExecutor mUiMainExecutor = new FakeExecutor(new FakeSystemClock());
204     private FakeExecutor mUiBgExecutor = new FakeExecutor(new FakeSystemClock());
205 
206     private FalsingCollectorFake mFalsingCollector;
207 
208     private @Mock CentralSurfaces mCentralSurfaces;
209     private @Mock UiEventLogger mUiEventLogger;
210     private @Mock SessionTracker mSessionTracker;
211     private @Mock SystemSettings mSystemSettings;
212     private @Mock SecureSettings mSecureSettings;
213     private @Mock AlarmManager mAlarmManager;
214     private FakeSystemClock mSystemClock;
215     private final FakeWallpaperRepository mWallpaperRepository = new FakeWallpaperRepository();
216 
217     /** Most recent value passed to {@link KeyguardStateController#notifyKeyguardGoingAway}. */
218     private boolean mKeyguardGoingAway = false;
219 
220     private @Mock CoroutineDispatcher mDispatcher;
221     private @Mock DreamViewModel mDreamViewModel;
222     private @Mock CommunalTransitionViewModel mCommunalTransitionViewModel;
223     private @Mock SystemPropertiesHelper mSystemPropertiesHelper;
224 
225     private FakeFeatureFlags mFeatureFlags;
226     private final int mDefaultUserId = 100;
227 
228     @Before
setUp()229     public void setUp() throws Exception {
230         MockitoAnnotations.initMocks(this);
231         mFalsingCollector = new FalsingCollectorFake();
232         mSystemClock = new FakeSystemClock();
233         when(mLockPatternUtils.getDevicePolicyManager()).thenReturn(mDevicePolicyManager);
234         when(mPowerManager.newWakeLock(anyInt(), any())).thenReturn(mock(WakeLock.class));
235         when(mPowerManager.isInteractive()).thenReturn(true);
236         mContext.addMockSystemService(Context.ALARM_SERVICE, mAlarmManager);
237         final ViewRootImpl testViewRoot = mock(ViewRootImpl.class);
238         when(testViewRoot.getView()).thenReturn(mock(View.class));
239         when(mStatusBarKeyguardViewManager.getViewRootImpl()).thenReturn(testViewRoot);
240         when(mDreamViewModel.getDreamAlpha())
241                 .thenReturn(mock(Flow.class));
242         when(mDreamViewModel.getTransitionEnded())
243                 .thenReturn(mock(Flow.class));
244         when(mCommunalTransitionViewModel.getShowCommunalFromOccluded())
245                 .thenReturn(mock(Flow.class));
246         when(mCommunalTransitionViewModel.getTransitionFromOccludedEnded())
247                 .thenReturn(mock(Flow.class));
248         when(mSelectedUserInteractor.getSelectedUserId()).thenReturn(mDefaultUserId);
249         when(mSelectedUserInteractor.getSelectedUserId(anyBoolean())).thenReturn(mDefaultUserId);
250         mNotificationShadeWindowController = new NotificationShadeWindowControllerImpl(
251                 mContext,
252                 new FakeWindowRootViewComponent.Factory(mock(WindowRootView.class)),
253                 mWindowManager,
254                 mActivityManager,
255                 mDozeParameters,
256                 mStatusBarStateController,
257                 mConfigurationController,
258                 mViewMediator,
259                 mKeyguardBypassController,
260                 mUiMainExecutor,
261                 mUiBgExecutor,
262                 mColorExtractor,
263                 mDumpManager,
264                 mKeyguardStateController,
265                 mAuthController,
266                 () -> mShadeInteractor,
267                 mShadeWindowLogger,
268                 () -> mSelectedUserInteractor,
269                 mUserTracker,
270                 mKosmos::getCommunalInteractor);
271         mFeatureFlags = new FakeFeatureFlags();
272         mSetFlagsRule.enableFlags(FLAG_REFACTOR_GET_CURRENT_USER);
273         mSetFlagsRule.disableFlags(FLAG_KEYGUARD_WM_STATE_REFACTOR);
274 
275         DejankUtils.setImmediate(true);
276 
277         // Keep track of what we told KeyguardStateController about whether we're going away or
278         // not.
279         mKeyguardGoingAway = false;
280         doAnswer(invocation -> {
281             mKeyguardGoingAway = invocation.getArgument(0);
282             return null;
283         }).when(mKeyguardStateController).notifyKeyguardGoingAway(anyBoolean());
284 
285         createAndStartViewMediator();
286     }
287 
288     /**
289      * After each test, verify that System UI's going away/showing state matches the most recent
290      * calls we made to ATMS.
291      *
292      * This will help us catch showing and going away state mismatch issues.
293      */
294     @After
assertATMSAndKeyguardViewMediatorStatesMatch()295     public void assertATMSAndKeyguardViewMediatorStatesMatch() {
296         try {
297             if (mKeyguardGoingAway) {
298                 assertATMSKeyguardGoingAway();
299             } else {
300                 assertATMSLockScreenShowing(mViewMediator.isShowing());
301             }
302 
303         } catch (Exception e) {
304             // Just so we don't have to add the exception signature to every test.
305             fail();
306         }
307     }
308 
309     @Test
310     @TestableLooper.RunWithLooper(setAsMainLooper = true)
onLockdown_showKeyguard_evenIfKeyguardIsNotEnabledExternally()311     public void onLockdown_showKeyguard_evenIfKeyguardIsNotEnabledExternally() {
312         // GIVEN keyguard is not enabled and isn't showing
313         mViewMediator.onSystemReady();
314         mViewMediator.setKeyguardEnabled(false);
315         TestableLooper.get(this).processAllMessages();
316         captureKeyguardUpdateMonitorCallback();
317         assertFalse(mViewMediator.isShowingAndNotOccluded());
318 
319         // WHEN lockdown occurs
320         when(mLockPatternUtils.isUserInLockdown(anyInt())).thenReturn(true);
321         mKeyguardUpdateMonitorCallbackCaptor.getValue().onStrongAuthStateChanged(0);
322 
323         // THEN keyguard is shown
324         TestableLooper.get(this).processAllMessages();
325         assertTrue(mViewMediator.isShowingAndNotOccluded());
326     }
327 
328     @Test
329     @TestableLooper.RunWithLooper(setAsMainLooper = true)
showKeyguardAfterKeyguardNotEnabled()330     public void showKeyguardAfterKeyguardNotEnabled() {
331         // GIVEN feature is enabled
332         final FoldGracePeriodProvider mockedFoldGracePeriodProvider =
333                 mock(FoldGracePeriodProvider.class);
334         mViewMediator.mFoldGracePeriodProvider = mockedFoldGracePeriodProvider;
335         when(mockedFoldGracePeriodProvider.isEnabled()).thenReturn(true);
336         when(mUpdateMonitor.isDeviceProvisioned()).thenReturn(true);
337 
338         // GIVEN keyguard is not enabled and isn't showing
339         mViewMediator.onSystemReady();
340         mViewMediator.setKeyguardEnabled(false);
341         TestableLooper.get(this).processAllMessages();
342         captureKeyguardUpdateMonitorCallback();
343         assertFalse(mViewMediator.isShowingAndNotOccluded());
344 
345         // WHEN showKeyguard is requested
346         mViewMediator.showDismissibleKeyguard();
347 
348         // THEN keyguard is shown
349         TestableLooper.get(this).processAllMessages();
350         assertTrue(mViewMediator.isShowingAndNotOccluded());
351     }
352 
353     @Test
354     @TestableLooper.RunWithLooper(setAsMainLooper = true)
doNotShowKeyguard_deviceNotProvisioned()355     public void doNotShowKeyguard_deviceNotProvisioned() {
356         // GIVEN feature is enabled
357         final FoldGracePeriodProvider mockedFoldGracePeriodProvider =
358                 mock(FoldGracePeriodProvider.class);
359         mViewMediator.mFoldGracePeriodProvider = mockedFoldGracePeriodProvider;
360         when(mockedFoldGracePeriodProvider.isEnabled()).thenReturn(true);
361 
362         // GIVEN keyguard is not enabled and isn't showing
363         mViewMediator.onSystemReady();
364         mViewMediator.setKeyguardEnabled(false);
365         TestableLooper.get(this).processAllMessages();
366         captureKeyguardUpdateMonitorCallback();
367         assertFalse(mViewMediator.isShowingAndNotOccluded());
368 
369         // WHEN device is NOT provisioned
370         when(mUpdateMonitor.isDeviceProvisioned()).thenReturn(false);
371 
372         // WHEN showKeyguard is requested
373         mViewMediator.showDismissibleKeyguard();
374 
375         // THEN keyguard is NOT shown
376         TestableLooper.get(this).processAllMessages();
377         assertFalse(mViewMediator.isShowingAndNotOccluded());
378     }
379 
380     @Test
381     @TestableLooper.RunWithLooper(setAsMainLooper = true)
showKeyguardAfterKeyguardNotEnabled_featureNotEnabled()382     public void showKeyguardAfterKeyguardNotEnabled_featureNotEnabled() {
383         // GIVEN feature is NOT enabled
384         final FoldGracePeriodProvider mockedFoldGracePeriodProvider =
385                 mock(FoldGracePeriodProvider.class);
386         mViewMediator.mFoldGracePeriodProvider = mockedFoldGracePeriodProvider;
387         when(mockedFoldGracePeriodProvider.isEnabled()).thenReturn(false);
388         when(mUpdateMonitor.isDeviceProvisioned()).thenReturn(true);
389 
390         // GIVEN keyguard is not enabled and isn't showing
391         mViewMediator.onSystemReady();
392         mViewMediator.setKeyguardEnabled(false);
393         TestableLooper.get(this).processAllMessages();
394         captureKeyguardUpdateMonitorCallback();
395         assertFalse(mViewMediator.isShowingAndNotOccluded());
396 
397         // WHEN showKeyguard is requested
398         mViewMediator.showDismissibleKeyguard();
399 
400         // THEN keyguard is still NOT shown
401         TestableLooper.get(this).processAllMessages();
402         assertFalse(mViewMediator.isShowingAndNotOccluded());
403     }
404 
405     @Test
406     @TestableLooper.RunWithLooper(setAsMainLooper = true)
doNotHideKeyguard_whenLockdown_onKeyguardNotEnabledExternally()407     public void doNotHideKeyguard_whenLockdown_onKeyguardNotEnabledExternally() {
408         // GIVEN keyguard is enabled and lockdown occurred so the keyguard is showing
409         mViewMediator.onSystemReady();
410         mViewMediator.setKeyguardEnabled(true);
411         TestableLooper.get(this).processAllMessages();
412         captureKeyguardUpdateMonitorCallback();
413         when(mLockPatternUtils.isUserInLockdown(anyInt())).thenReturn(true);
414         mKeyguardUpdateMonitorCallbackCaptor.getValue().onStrongAuthStateChanged(0);
415         assertTrue(mViewMediator.isShowingAndNotOccluded());
416 
417         // WHEN keyguard is externally not enabled anymore
418         mViewMediator.setKeyguardEnabled(false);
419 
420         // THEN keyguard is NOT dismissed; it continues to show
421         TestableLooper.get(this).processAllMessages();
422         assertTrue(mViewMediator.isShowingAndNotOccluded());
423     }
424 
425     @Test
testOnGoingToSleep_UpdatesKeyguardGoingAway()426     public void testOnGoingToSleep_UpdatesKeyguardGoingAway() {
427         mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER);
428         verify(mUpdateMonitor).dispatchKeyguardGoingAway(false);
429         verify(mStatusBarKeyguardViewManager, never()).setKeyguardGoingAwayState(anyBoolean());
430     }
431 
432     @Test
433     @TestableLooper.RunWithLooper(setAsMainLooper = true)
testOnStartedWakingUp_whileSleeping_ifWakeAndUnlocking_doesNotShowKeyguard()434     public void testOnStartedWakingUp_whileSleeping_ifWakeAndUnlocking_doesNotShowKeyguard() {
435         when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false);
436         when(mLockPatternUtils.getPowerButtonInstantlyLocks(anyInt())).thenReturn(true);
437         mViewMediator.onSystemReady();
438         TestableLooper.get(this).processAllMessages();
439 
440         mViewMediator.setShowingLocked(false);
441         TestableLooper.get(this).processAllMessages();
442 
443         mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER);
444         mViewMediator.onWakeAndUnlocking(false);
445         mViewMediator.onStartedWakingUp(OFF_BECAUSE_OF_USER, false);
446         TestableLooper.get(this).processAllMessages();
447 
448         assertFalse(mViewMediator.isShowingAndNotOccluded());
449         verify(mKeyguardStateController, never()).notifyKeyguardState(eq(true), anyBoolean());
450     }
451 
452     @Test
453     @TestableLooper.RunWithLooper(setAsMainLooper = true)
testOnStartedWakingUp_whileSleeping_ifNotWakeAndUnlocking_showsKeyguard()454     public void testOnStartedWakingUp_whileSleeping_ifNotWakeAndUnlocking_showsKeyguard() {
455         when(mLockPatternUtils.isLockScreenDisabled(anyInt())).thenReturn(false);
456         when(mLockPatternUtils.getPowerButtonInstantlyLocks(anyInt())).thenReturn(true);
457         mViewMediator.onSystemReady();
458         TestableLooper.get(this).processAllMessages();
459 
460         mViewMediator.setShowingLocked(false);
461         TestableLooper.get(this).processAllMessages();
462 
463         mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER);
464         mViewMediator.onStartedWakingUp(OFF_BECAUSE_OF_USER, false);
465 
466         TestableLooper.get(this).processAllMessages();
467 
468         assertTrue(mViewMediator.isShowingAndNotOccluded());
469     }
470 
471     @Test
testRegisterDumpable()472     public void testRegisterDumpable() {
473         verify(mDumpManager).registerDumpable(mViewMediator);
474         verify(mStatusBarKeyguardViewManager, never()).setKeyguardGoingAwayState(anyBoolean());
475     }
476 
477     @Test
testKeyguardGone_notGoingaway()478     public void testKeyguardGone_notGoingaway() {
479         mViewMediator.mViewMediatorCallback.keyguardGone();
480         verify(mStatusBarKeyguardViewManager).setKeyguardGoingAwayState(eq(false));
481     }
482 
483     @Test
testIsAnimatingScreenOff()484     public void testIsAnimatingScreenOff() {
485         when(mDozeParameters.shouldControlUnlockedScreenOff()).thenReturn(true);
486         when(mDozeParameters.shouldAnimateDozingChange()).thenReturn(true);
487 
488         mViewMediator.onFinishedGoingToSleep(OFF_BECAUSE_OF_USER, false);
489         mViewMediator.setDozing(true);
490 
491         // Mid-doze, we should be animating the screen off animation.
492         mViewMediator.onDozeAmountChanged(0.5f, 0.5f);
493         assertTrue(mViewMediator.isAnimatingScreenOff());
494 
495         // Once we're 100% dozed, the screen off animation should be completed.
496         mViewMediator.onDozeAmountChanged(1f, 1f);
497         assertFalse(mViewMediator.isAnimatingScreenOff());
498     }
499 
500     @Test
501     @TestableLooper.RunWithLooper(setAsMainLooper = true)
wakeupFromDreamingWhenKeyguardHides_orderUnlockAndWakeOff()502     public void wakeupFromDreamingWhenKeyguardHides_orderUnlockAndWakeOff() {
503         createAndStartViewMediator(false);
504 
505         mViewMediator.onSystemReady();
506         TestableLooper.get(this).processAllMessages();
507 
508         // Given device is dreaming
509         when(mUpdateMonitor.isDreaming()).thenReturn(true);
510 
511         // When keyguard is going away
512         mKeyguardStateController.notifyKeyguardGoingAway(true);
513 
514         // And keyguard is disabled which will call #handleHide
515         mViewMediator.setKeyguardEnabled(false);
516         TestableLooper.get(this).processAllMessages();
517 
518         // Then dream should wake up
519         verify(mPowerManager).wakeUp(anyLong(), anyInt(),
520                 eq("com.android.systemui:UNLOCK_DREAMING"));
521     }
522 
523     @Test
524     @TestableLooper.RunWithLooper(setAsMainLooper = true)
wakeupFromDreamingWhenKeyguardHides_orderUnlockAndWakeOn()525     public void wakeupFromDreamingWhenKeyguardHides_orderUnlockAndWakeOn() {
526         createAndStartViewMediator(true);
527 
528         mViewMediator.onSystemReady();
529         TestableLooper.get(this).processAllMessages();
530         when(mPowerManager.isInteractive()).thenReturn(true);
531 
532         // Given device is dreaming
533         when(mUpdateMonitor.isDreaming()).thenReturn(true);
534 
535         // When keyguard is going away
536         mKeyguardStateController.notifyKeyguardGoingAway(true);
537 
538         // And keyguard is disabled which will call #handleHide
539         mViewMediator.setKeyguardEnabled(false);
540         TestableLooper.get(this).processAllMessages();
541 
542         mViewMediator.mViewMediatorCallback.keyguardDonePending(mDefaultUserId);
543         mViewMediator.mViewMediatorCallback.readyForKeyguardDone();
544         final ArgumentCaptor<Runnable> animationRunnableCaptor =
545                 ArgumentCaptor.forClass(Runnable.class);
546         verify(mStatusBarKeyguardViewManager).startPreHideAnimation(
547                 animationRunnableCaptor.capture());
548 
549         when(mStatusBarStateController.isDreaming()).thenReturn(true);
550         when(mStatusBarStateController.isDozing()).thenReturn(false);
551         animationRunnableCaptor.getValue().run();
552 
553         when(mKeyguardStateController.isShowing()).thenReturn(false);
554         mViewMediator.mViewMediatorCallback.keyguardGone();
555 
556         // Then dream should wake up
557         verify(mPowerManager).wakeUp(anyLong(), anyInt(),
558                 eq("com.android.systemui:UNLOCK_DREAMING"));
559     }
560 
561     @Test
562     @TestableLooper.RunWithLooper(setAsMainLooper = true)
restoreBouncerWhenSimLockedAndKeyguardIsGoingAway()563     public void restoreBouncerWhenSimLockedAndKeyguardIsGoingAway() {
564         // When showing and provisioned
565         mViewMediator.onSystemReady();
566         when(mUpdateMonitor.isDeviceProvisioned()).thenReturn(true);
567         mViewMediator.setShowingLocked(true);
568 
569         // and a SIM becomes locked and requires a PIN
570         mViewMediator.mUpdateCallback.onSimStateChanged(
571                 1 /* subId */,
572                 0 /* slotId */,
573                 TelephonyManager.SIM_STATE_PIN_REQUIRED);
574 
575         // and the keyguard goes away
576         mViewMediator.setShowingLocked(false);
577         when(mKeyguardStateController.isShowing()).thenReturn(false);
578         mViewMediator.mUpdateCallback.onKeyguardVisibilityChanged(false);
579 
580         TestableLooper.get(this).processAllMessages();
581 
582         // then make sure it comes back
583         verify(mStatusBarKeyguardViewManager, atLeast(1)).show(null);
584     }
585 
586     @Test
587     @TestableLooper.RunWithLooper(setAsMainLooper = true)
restoreBouncerWhenSimLockedAndKeyguardIsGoingAway_initiallyNotShowing()588     public void restoreBouncerWhenSimLockedAndKeyguardIsGoingAway_initiallyNotShowing() {
589         // When showing and provisioned
590         mViewMediator.onSystemReady();
591         when(mUpdateMonitor.isDeviceProvisioned()).thenReturn(true);
592         mViewMediator.setShowingLocked(false);
593 
594         // and a SIM becomes locked and requires a PIN
595         mViewMediator.mUpdateCallback.onSimStateChanged(
596                 1 /* subId */,
597                 0 /* slotId */,
598                 TelephonyManager.SIM_STATE_PIN_REQUIRED);
599 
600         // and the keyguard goes away
601         mViewMediator.setShowingLocked(false);
602         when(mKeyguardStateController.isShowing()).thenReturn(false);
603         mViewMediator.mUpdateCallback.onKeyguardVisibilityChanged(false);
604 
605         TestableLooper.get(this).processAllMessages();
606 
607         // then make sure it comes back
608         verify(mStatusBarKeyguardViewManager, atLeast(1)).show(null);
609     }
610 
611     @Test
testBouncerPrompt_deviceLockedByAdmin()612     public void testBouncerPrompt_deviceLockedByAdmin() {
613         // GIVEN no trust agents enabled and biometrics aren't enrolled
614         when(mUpdateMonitor.isTrustUsuallyManaged(anyInt())).thenReturn(false);
615         when(mUpdateMonitor.isUnlockingWithBiometricsPossible(anyInt())).thenReturn(false);
616 
617         // WHEN the strong auth reason is AFTER_DPM_LOCK_NOW
618         KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
619                 mock(KeyguardUpdateMonitor.StrongAuthTracker.class);
620         when(mUpdateMonitor.getStrongAuthTracker()).thenReturn(strongAuthTracker);
621         when(strongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
622                 STRONG_AUTH_REQUIRED_AFTER_DPM_LOCK_NOW);
623 
624         // THEN the bouncer prompt reason should return PROMPT_REASON_DEVICE_ADMIN
625         assertEquals(KeyguardSecurityView.PROMPT_REASON_DEVICE_ADMIN,
626                 mViewMediator.mViewMediatorCallback.getBouncerPromptReason());
627     }
628 
629     @Test
testBouncerPrompt_deviceLockedByAdaptiveAuth()630     public void testBouncerPrompt_deviceLockedByAdaptiveAuth() {
631         // GIVEN no trust agents enabled and biometrics aren't enrolled
632         when(mUpdateMonitor.isTrustUsuallyManaged(anyInt())).thenReturn(false);
633         when(mUpdateMonitor.isUnlockingWithBiometricsPossible(anyInt())).thenReturn(false);
634 
635         // WHEN the strong auth reason is SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST
636         KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
637                 mock(KeyguardUpdateMonitor.StrongAuthTracker.class);
638         when(mUpdateMonitor.getStrongAuthTracker()).thenReturn(strongAuthTracker);
639         when(strongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
640         when(strongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
641                 SOME_AUTH_REQUIRED_AFTER_ADAPTIVE_AUTH_REQUEST);
642 
643         // THEN the bouncer prompt reason should return PROMPT_REASON_ADAPTIVE_AUTH_REQUEST
644         assertEquals(KeyguardSecurityView.PROMPT_REASON_ADAPTIVE_AUTH_REQUEST,
645                 mViewMediator.mViewMediatorCallback.getBouncerPromptReason());
646     }
647 
648     @Test
testBouncerPrompt_deviceRestartedDueToMainlineUpdate()649     public void testBouncerPrompt_deviceRestartedDueToMainlineUpdate() {
650         // GIVEN biometrics enrolled
651         when(mUpdateMonitor.isUnlockingWithBiometricsPossible(anyInt())).thenReturn(true);
652 
653         // WHEN reboot caused by ota update
654         KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
655                 mock(KeyguardUpdateMonitor.StrongAuthTracker.class);
656         when(mUpdateMonitor.getStrongAuthTracker()).thenReturn(strongAuthTracker);
657         when(strongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(false);
658         when(mSystemPropertiesHelper.get(SYS_BOOT_REASON_PROP)).thenReturn(REBOOT_MAINLINE_UPDATE);
659 
660         // THEN the bouncer prompt reason should return PROMPT_REASON_RESTART_FOR_OTA
661         assertEquals(KeyguardSecurityView.PROMPT_REASON_RESTART_FOR_MAINLINE_UPDATE,
662                 mViewMediator.mViewMediatorCallback.getBouncerPromptReason());
663     }
664 
665     @Test
testBouncerPrompt_afterUserLockDown()666     public void testBouncerPrompt_afterUserLockDown() {
667         // GIVEN biometrics enrolled
668         when(mUpdateMonitor.isUnlockingWithBiometricsPossible(anyInt())).thenReturn(true);
669 
670         // WHEN user has locked down the device
671         KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
672                 mock(KeyguardUpdateMonitor.StrongAuthTracker.class);
673         when(mUpdateMonitor.getStrongAuthTracker()).thenReturn(strongAuthTracker);
674         when(strongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
675         when(strongAuthTracker.getStrongAuthForUser(anyInt()))
676                 .thenReturn(STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
677 
678         // THEN the bouncer prompt reason should return PROMPT_REASON_USER_REQUEST
679         assertEquals(KeyguardSecurityView.PROMPT_REASON_USER_REQUEST,
680                 mViewMediator.mViewMediatorCallback.getBouncerPromptReason());
681     }
682 
683     @Test
testBouncerPrompt_afterUserLockDown_noBiometricsEnrolled()684     public void testBouncerPrompt_afterUserLockDown_noBiometricsEnrolled() {
685         // GIVEN biometrics not enrolled
686         when(mUpdateMonitor.isUnlockingWithBiometricsPossible(anyInt())).thenReturn(false);
687 
688         // WHEN user has locked down the device
689         KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
690                 mock(KeyguardUpdateMonitor.StrongAuthTracker.class);
691         when(mUpdateMonitor.getStrongAuthTracker()).thenReturn(strongAuthTracker);
692         when(strongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
693         when(strongAuthTracker.getStrongAuthForUser(anyInt()))
694                 .thenReturn(STRONG_AUTH_REQUIRED_AFTER_USER_LOCKDOWN);
695 
696         // THEN the bouncer prompt reason should return the default prompt
697         assertEquals(KeyguardSecurityView.PROMPT_REASON_NONE,
698                 mViewMediator.mViewMediatorCallback.getBouncerPromptReason());
699     }
700 
701     @Test
testBouncerPrompt_nonStrongIdleTimeout()702     public void testBouncerPrompt_nonStrongIdleTimeout() {
703         // GIVEN trust agents enabled and biometrics are enrolled
704         when(mUpdateMonitor.isTrustUsuallyManaged(anyInt())).thenReturn(true);
705         when(mUpdateMonitor.isUnlockingWithBiometricsPossible(anyInt())).thenReturn(true);
706 
707         // WHEN the strong auth reason is STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT
708         KeyguardUpdateMonitor.StrongAuthTracker strongAuthTracker =
709                 mock(KeyguardUpdateMonitor.StrongAuthTracker.class);
710         when(mUpdateMonitor.getStrongAuthTracker()).thenReturn(strongAuthTracker);
711         when(strongAuthTracker.hasUserAuthenticatedSinceBoot()).thenReturn(true);
712         when(strongAuthTracker.isNonStrongBiometricAllowedAfterIdleTimeout(
713                 anyInt())).thenReturn(false);
714         when(strongAuthTracker.getStrongAuthForUser(anyInt())).thenReturn(
715                 STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT);
716 
717         // THEN the bouncer prompt reason should return
718         // STRONG_AUTH_REQUIRED_AFTER_NON_STRONG_BIOMETRICS_TIMEOUT
719         assertEquals(KeyguardSecurityView.PROMPT_REASON_NON_STRONG_BIOMETRIC_TIMEOUT,
720                 mViewMediator.mViewMediatorCallback.getBouncerPromptReason());
721     }
722 
723     @Test
lockAfterScreenTimeoutUsesValueFromSettings()724     public void lockAfterScreenTimeoutUsesValueFromSettings() {
725         int currentUserId = 99;
726         int userSpecificTimeout = 5999;
727 
728         when(mSelectedUserInteractor.getSelectedUserId()).thenReturn(currentUserId);
729         when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(false);
730         when(mDevicePolicyManager.getMaximumTimeToLock(null, currentUserId)).thenReturn(0L);
731         when(mSecureSettings.getIntForUser(LOCK_SCREEN_LOCK_AFTER_TIMEOUT,
732                 KEYGUARD_LOCK_AFTER_DELAY_DEFAULT, currentUserId)).thenReturn(userSpecificTimeout);
733         mSystemClock.setElapsedRealtime(0L);
734         ArgumentCaptor<PendingIntent> pendingIntent = ArgumentCaptor.forClass(PendingIntent.class);
735 
736         mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_TIMEOUT);
737 
738         verify(mAlarmManager).setExactAndAllowWhileIdle(eq(AlarmManager.ELAPSED_REALTIME_WAKEUP),
739                 eq(Long.valueOf(userSpecificTimeout)), pendingIntent.capture());
740         assertEquals(DELAYED_KEYGUARD_ACTION, pendingIntent.getValue().getIntent().getAction());
741     }
742 
743     @Test
testHideSurfaceBehindKeyguardMarksKeyguardNotGoingAway()744     public void testHideSurfaceBehindKeyguardMarksKeyguardNotGoingAway() {
745         mViewMediator.hideSurfaceBehindKeyguard();
746 
747         verify(mKeyguardStateController).notifyKeyguardGoingAway(false);
748     }
749 
750     @Test
testUpdateIsKeyguardAfterOccludeAnimationEnds()751     public void testUpdateIsKeyguardAfterOccludeAnimationEnds() {
752         mViewMediator.mOccludeAnimationController.onTransitionAnimationEnd(
753                 false /* isExpandingFullyAbove */);
754 
755         // Since the updateIsKeyguard call is delayed during the animation, ensure it's called once
756         // it ends.
757         verify(mCentralSurfaces).updateIsKeyguard();
758     }
759 
760     @Test
testUpdateIsKeyguardAfterOccludeAnimationIsCancelled()761     public void testUpdateIsKeyguardAfterOccludeAnimationIsCancelled() {
762         mViewMediator.mOccludeAnimationController.onTransitionAnimationCancelled(
763                 null /* newKeyguardOccludedState */);
764 
765         // Since the updateIsKeyguard call is delayed during the animation, ensure it's called if
766         // it's cancelled.
767         verify(mCentralSurfaces).updateIsKeyguard();
768     }
769 
770     @Test
771     @TestableLooper.RunWithLooper(setAsMainLooper = true)
testCancelKeyguardExitAnimation_noPendingLock_keyguardWillNotBeShowing()772     public void testCancelKeyguardExitAnimation_noPendingLock_keyguardWillNotBeShowing() {
773         startMockKeyguardExitAnimation();
774         cancelMockKeyguardExitAnimation();
775 
776         // There should not be a pending lock, but try to handle it anyway to ensure one isn't set.
777         mViewMediator.maybeHandlePendingLock();
778         TestableLooper.get(this).processAllMessages();
779 
780         assertFalse(mViewMediator.isShowingAndNotOccluded());
781         verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(false);
782     }
783 
784     @Test
785     @TestableLooper.RunWithLooper(setAsMainLooper = true)
testCancelKeyguardExitAnimationDueToSleep_withPendingLock_keyguardWillBeShowing()786     public void testCancelKeyguardExitAnimationDueToSleep_withPendingLock_keyguardWillBeShowing() {
787         startMockKeyguardExitAnimation();
788 
789         mViewMediator.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON);
790         mViewMediator.onFinishedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, false);
791 
792         cancelMockKeyguardExitAnimation();
793 
794         mViewMediator.maybeHandlePendingLock();
795         TestableLooper.get(this).processAllMessages();
796 
797         assertTrue(mViewMediator.isShowingAndNotOccluded());
798         verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(true);
799     }
800 
801     @Test
802     @TestableLooper.RunWithLooper(setAsMainLooper = true)
testCancelKeyguardExitAnimationThenSleep_withPendingLock_keyguardWillBeShowing()803     public void testCancelKeyguardExitAnimationThenSleep_withPendingLock_keyguardWillBeShowing() {
804         startMockKeyguardExitAnimation();
805         cancelMockKeyguardExitAnimation();
806 
807         // Calling cancel above results in keyguard not visible, as there is no pending lock
808         verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(false);
809 
810         mViewMediator.maybeHandlePendingLock();
811         TestableLooper.get(this).processAllMessages();
812 
813         mViewMediator.onStartedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON);
814         mViewMediator.onFinishedGoingToSleep(PowerManager.GO_TO_SLEEP_REASON_POWER_BUTTON, false);
815 
816         mViewMediator.maybeHandlePendingLock();
817         TestableLooper.get(this).processAllMessages();
818 
819         assertTrue(mViewMediator.isShowingAndNotOccluded());
820     }
821 
822     @Test
823     @TestableLooper.RunWithLooper(setAsMainLooper = true)
testStartKeyguardExitAnimation_expectSurfaceBehindRemoteAnimationAndExits()824     public void testStartKeyguardExitAnimation_expectSurfaceBehindRemoteAnimationAndExits() {
825         startMockKeyguardExitAnimation();
826         assertTrue(mViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind());
827 
828         mViewMediator.mViewMediatorCallback.keyguardDonePending(mDefaultUserId);
829         mViewMediator.mViewMediatorCallback.readyForKeyguardDone();
830         TestableLooper.get(this).processAllMessages();
831         verify(mKeyguardUnlockAnimationController).notifyFinishedKeyguardExitAnimation(false);
832     }
833 
834     @Test
835     @TestableLooper.RunWithLooper(setAsMainLooper = true)
testKeyguardDelayedOnGoingToSleep_ifScreenOffAnimationWillPlayButIsntPlayingYet()836     public void testKeyguardDelayedOnGoingToSleep_ifScreenOffAnimationWillPlayButIsntPlayingYet() {
837         mViewMediator.onSystemReady();
838         TestableLooper.get(this).processAllMessages();
839 
840         mViewMediator.setShowingLocked(false);
841         TestableLooper.get(this).processAllMessages();
842 
843         mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER);
844         TestableLooper.get(this).processAllMessages();
845 
846         when(mScreenOffAnimationController.shouldDelayKeyguardShow()).thenReturn(true);
847         when(mScreenOffAnimationController.isKeyguardShowDelayed()).thenReturn(false);
848         mViewMediator.onFinishedGoingToSleep(OFF_BECAUSE_OF_USER, false);
849         TestableLooper.get(this).processAllMessages();
850 
851         assertFalse(mViewMediator.isShowingAndNotOccluded());
852     }
853 
854     @Test
855     @TestableLooper.RunWithLooper(setAsMainLooper = true)
testKeyguardNotDelayedOnGoingToSleep_ifScreenOffAnimationWillNotPlay()856     public void testKeyguardNotDelayedOnGoingToSleep_ifScreenOffAnimationWillNotPlay() {
857         mViewMediator.onSystemReady();
858         TestableLooper.get(this).processAllMessages();
859 
860         mViewMediator.setShowingLocked(false);
861         TestableLooper.get(this).processAllMessages();
862 
863         mViewMediator.onStartedGoingToSleep(OFF_BECAUSE_OF_USER);
864         TestableLooper.get(this).processAllMessages();
865 
866         when(mScreenOffAnimationController.shouldDelayKeyguardShow()).thenReturn(false);
867         mViewMediator.onFinishedGoingToSleep(OFF_BECAUSE_OF_USER, false);
868         TestableLooper.get(this).processAllMessages();
869 
870         assertTrue(mViewMediator.isShowingAndNotOccluded());
871     }
872 
873     @Test
testWakeAndUnlocking()874     public void testWakeAndUnlocking() {
875         mViewMediator.onWakeAndUnlocking(false);
876         verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(anyBoolean());
877     }
878 
879     @Test
testWakeAndUnlockingOverDream()880     public void testWakeAndUnlockingOverDream() {
881         // Ensure ordering unlock and wake is enabled.
882         createAndStartViewMediator(true);
883 
884         // Send signal to wake
885         mViewMediator.onWakeAndUnlocking(true);
886 
887         // Ensure not woken up yet
888         verify(mPowerManager, never()).wakeUp(anyLong(), anyInt(), anyString());
889 
890         // Verify keyguard told of authentication
891         verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(anyBoolean());
892         mViewMediator.mViewMediatorCallback.keyguardDonePending(mDefaultUserId);
893         mViewMediator.mViewMediatorCallback.readyForKeyguardDone();
894         final ArgumentCaptor<Runnable> animationRunnableCaptor =
895                 ArgumentCaptor.forClass(Runnable.class);
896         verify(mStatusBarKeyguardViewManager).startPreHideAnimation(
897                 animationRunnableCaptor.capture());
898 
899         when(mStatusBarStateController.isDreaming()).thenReturn(true);
900         when(mStatusBarStateController.isDozing()).thenReturn(false);
901         animationRunnableCaptor.getValue().run();
902 
903         when(mKeyguardStateController.isShowing()).thenReturn(false);
904         mViewMediator.mViewMediatorCallback.keyguardGone();
905 
906         // Verify woken up now.
907         verify(mPowerManager).wakeUp(anyLong(), anyInt(), anyString());
908     }
909 
910     @Test
testWakeAndUnlockingOverDream_signalAuthenticateIfStillShowing()911     public void testWakeAndUnlockingOverDream_signalAuthenticateIfStillShowing() {
912         // Ensure ordering unlock and wake is enabled.
913         createAndStartViewMediator(true);
914 
915         // Send signal to wake
916         mViewMediator.onWakeAndUnlocking(true);
917 
918         // Ensure not woken up yet
919         verify(mPowerManager, never()).wakeUp(anyLong(), anyInt(), anyString());
920 
921         // Verify keyguard told of authentication
922         verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(anyBoolean());
923         clearInvocations(mStatusBarKeyguardViewManager);
924         mViewMediator.mViewMediatorCallback.keyguardDonePending(mDefaultUserId);
925         mViewMediator.mViewMediatorCallback.readyForKeyguardDone();
926         final ArgumentCaptor<Runnable> animationRunnableCaptor =
927                 ArgumentCaptor.forClass(Runnable.class);
928         verify(mStatusBarKeyguardViewManager).startPreHideAnimation(
929                 animationRunnableCaptor.capture());
930 
931         when(mStatusBarStateController.isDreaming()).thenReturn(true);
932         when(mStatusBarStateController.isDozing()).thenReturn(false);
933         animationRunnableCaptor.getValue().run();
934 
935         when(mKeyguardStateController.isShowing()).thenReturn(true);
936 
937         mViewMediator.mViewMediatorCallback.keyguardGone();
938 
939 
940         // Verify keyguard view controller informed of authentication again
941         verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(anyBoolean());
942     }
943 
944     @Test
testWakeAndUnlockingOverNonInteractiveDream_noWakeByKeyguardViewMediator()945     public void testWakeAndUnlockingOverNonInteractiveDream_noWakeByKeyguardViewMediator() {
946         // Send signal to wake
947         mViewMediator.onWakeAndUnlocking(false);
948 
949         // Ensure not woken up yet
950         verify(mPowerManager, never()).wakeUp(anyLong(), anyInt(), anyString());
951 
952         // Verify keyguard told of authentication
953         verify(mStatusBarKeyguardViewManager).notifyKeyguardAuthenticated(anyBoolean());
954         mViewMediator.mViewMediatorCallback.keyguardDonePending(mDefaultUserId);
955         mViewMediator.mViewMediatorCallback.readyForKeyguardDone();
956         final ArgumentCaptor<Runnable> animationRunnableCaptor =
957                 ArgumentCaptor.forClass(Runnable.class);
958         verify(mStatusBarKeyguardViewManager).startPreHideAnimation(
959                 animationRunnableCaptor.capture());
960 
961         when(mStatusBarStateController.isDreaming()).thenReturn(true);
962         when(mStatusBarStateController.isDozing()).thenReturn(false);
963         animationRunnableCaptor.getValue().run();
964 
965         when(mKeyguardStateController.isShowing()).thenReturn(false);
966         mViewMediator.mViewMediatorCallback.keyguardGone();
967 
968         // Verify not woken up.
969         verify(mPowerManager, never()).wakeUp(anyLong(), anyInt(), anyString());
970     }
971 
972     @Test
973     @TestableLooper.RunWithLooper(setAsMainLooper = true)
testDoKeyguardWhileInteractive_resets()974     public void testDoKeyguardWhileInteractive_resets() {
975         mViewMediator.setShowingLocked(true);
976         when(mKeyguardStateController.isShowing()).thenReturn(true);
977         TestableLooper.get(this).processAllMessages();
978 
979         mViewMediator.onSystemReady();
980         TestableLooper.get(this).processAllMessages();
981 
982         assertTrue(mViewMediator.isShowingAndNotOccluded());
983         verify(mStatusBarKeyguardViewManager).reset(false);
984     }
985 
986     @Test
987     @TestableLooper.RunWithLooper(setAsMainLooper = true)
testDoKeyguardWhileNotInteractive_showsInsteadOfResetting()988     public void testDoKeyguardWhileNotInteractive_showsInsteadOfResetting() {
989         mViewMediator.setShowingLocked(true);
990         when(mKeyguardStateController.isShowing()).thenReturn(true);
991         TestableLooper.get(this).processAllMessages();
992 
993         when(mPowerManager.isInteractive()).thenReturn(false);
994 
995         mViewMediator.onSystemReady();
996         TestableLooper.get(this).processAllMessages();
997 
998         assertTrue(mViewMediator.isShowingAndNotOccluded());
999         verify(mStatusBarKeyguardViewManager, never()).reset(anyBoolean());
1000     }
1001 
1002     @Test
1003     @TestableLooper.RunWithLooper(setAsMainLooper = true)
testStartKeyguardExitAnimation_thenCancelImmediately_doesNotResetAndUpdatesWM()1004     public void testStartKeyguardExitAnimation_thenCancelImmediately_doesNotResetAndUpdatesWM() {
1005         startMockKeyguardExitAnimation();
1006         cancelMockKeyguardExitAnimation();
1007 
1008         // This will trigger doKeyguardLocked and we can verify that we ask ATMS to show the
1009         // keyguard explicitly, even though we're already showing, because we cancelled immediately.
1010         mViewMediator.onSystemReady();
1011         reset(mActivityTaskManagerService);
1012         processAllMessagesAndBgExecutorMessages();
1013 
1014         verify(mStatusBarKeyguardViewManager, never()).reset(anyBoolean());
1015         assertATMSAndKeyguardViewMediatorStatesMatch();
1016     }
1017 
1018     @Test
1019     @TestableLooper.RunWithLooper(setAsMainLooper = true)
testStartKeyguardExitAnimation_whenNotInteractive_doesShowAndUpdatesWM()1020     public void testStartKeyguardExitAnimation_whenNotInteractive_doesShowAndUpdatesWM() {
1021         // If the exit animation was triggered but the device became non-interactive, make sure
1022         // relock happens
1023         when(mPowerManager.isInteractive()).thenReturn(false);
1024 
1025         startMockKeyguardExitAnimation();
1026         cancelMockKeyguardExitAnimation();
1027 
1028         verify(mStatusBarKeyguardViewManager, atLeast(1)).show(null);
1029         assertATMSAndKeyguardViewMediatorStatesMatch();
1030     }
1031 
1032     /**
1033      * Interactions with the ActivityTaskManagerService and others are posted to an executor that
1034      * doesn't use the testable looper. Use this method to ensure those are run as well.
1035      */
processAllMessagesAndBgExecutorMessages()1036     private void processAllMessagesAndBgExecutorMessages() {
1037         TestableLooper.get(this).processAllMessages();
1038         mUiBgExecutor.runAllReady();
1039     }
1040 
1041     /**
1042      * Configures mocks appropriately, then starts the keyguard exit animation.
1043      */
startMockKeyguardExitAnimation()1044     private void startMockKeyguardExitAnimation() {
1045         mViewMediator.onSystemReady();
1046         processAllMessagesAndBgExecutorMessages();
1047 
1048         mViewMediator.setShowingLocked(true);
1049 
1050         RemoteAnimationTarget[] apps = new RemoteAnimationTarget[]{
1051                 mock(RemoteAnimationTarget.class)
1052         };
1053         RemoteAnimationTarget[] wallpapers = new RemoteAnimationTarget[]{
1054                 mock(RemoteAnimationTarget.class)
1055         };
1056         IRemoteAnimationFinishedCallback callback = mock(IRemoteAnimationFinishedCallback.class);
1057 
1058         when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(true);
1059         mViewMediator.startKeyguardExitAnimation(TRANSIT_OLD_KEYGUARD_GOING_AWAY, apps, wallpapers,
1060                 null, callback);
1061         processAllMessagesAndBgExecutorMessages();
1062     }
1063 
1064     /**
1065      * Configures mocks appropriately, then cancels the keyguard exit animation.
1066      */
cancelMockKeyguardExitAnimation()1067     private void cancelMockKeyguardExitAnimation() {
1068         when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(false);
1069         mViewMediator.cancelKeyguardExitAnimation();
1070         processAllMessagesAndBgExecutorMessages();
1071     }
1072     /**
1073      * Asserts the last value passed to ATMS#setLockScreenShown. This should be confirmed alongside
1074      * {@link KeyguardViewMediator#isShowingAndNotOccluded()} to verify that state is not mismatched
1075      * between SysUI and WM.
1076      */
assertATMSLockScreenShowing(boolean showing)1077     private void assertATMSLockScreenShowing(boolean showing)
1078             throws RemoteException {
1079         // ATMS is called via bgExecutor, so make sure to run all of those calls first.
1080         processAllMessagesAndBgExecutorMessages();
1081 
1082         final InOrder orderedSetLockScreenShownCalls = inOrder(mActivityTaskManagerService);
1083         final ArgumentCaptor<Boolean> showingCaptor = ArgumentCaptor.forClass(Boolean.class);
1084         orderedSetLockScreenShownCalls
1085                 .verify(mActivityTaskManagerService, atLeastOnce())
1086                 .setLockScreenShown(showingCaptor.capture(), anyBoolean());
1087 
1088         // The captor will have the most recent setLockScreenShown call's value.
1089         assertEquals(showing, showingCaptor.getValue());
1090 
1091         // We're now just after the last setLockScreenShown call. If we expect the lockscreen to be
1092         // showing, ensure that we didn't subsequently ask for it to go away.
1093         if (showing) {
1094             orderedSetLockScreenShownCalls.verify(mActivityTaskManagerService, never())
1095                     .keyguardGoingAway(anyInt());
1096         }
1097     }
1098 
1099     /**
1100      * Asserts that we eventually called ATMS#keyguardGoingAway and did not subsequently call
1101      * ATMS#setLockScreenShown(true) which would cancel the going away.
1102      */
assertATMSKeyguardGoingAway()1103     private void assertATMSKeyguardGoingAway() throws RemoteException {
1104         // ATMS is called via bgExecutor, so make sure to run all of those calls first.
1105         processAllMessagesAndBgExecutorMessages();
1106 
1107         final InOrder orderedGoingAwayCalls = inOrder(mActivityTaskManagerService);
1108         orderedGoingAwayCalls.verify(mActivityTaskManagerService, atLeastOnce())
1109                 .keyguardGoingAway(anyInt());
1110 
1111         // Advance the inOrder to just past the last goingAway call. Let's make sure we didn't
1112         // re-show the lockscreen, which would cancel going away.
1113         orderedGoingAwayCalls.verify(mActivityTaskManagerService, never())
1114                 .setLockScreenShown(eq(true), anyBoolean());
1115     }
1116 
1117     @Test
1118     @TestableLooper.RunWithLooper(setAsMainLooper = true)
testNotStartingKeyguardWhenFlagIsDisabled()1119     public void testNotStartingKeyguardWhenFlagIsDisabled() {
1120         mViewMediator.setShowingLocked(false);
1121         when(mKeyguardStateController.isShowing()).thenReturn(false);
1122 
1123         mViewMediator.onDreamingStarted();
1124         assertFalse(mViewMediator.isShowingAndNotOccluded());
1125     }
1126 
1127     @Test
1128     @TestableLooper.RunWithLooper(setAsMainLooper = true)
testStartingKeyguardWhenFlagIsEnabled()1129     public void testStartingKeyguardWhenFlagIsEnabled() {
1130         mViewMediator.setShowingLocked(true);
1131         when(mKeyguardStateController.isShowing()).thenReturn(true);
1132 
1133         mViewMediator.onDreamingStarted();
1134         assertTrue(mViewMediator.isShowingAndNotOccluded());
1135     }
1136 
1137     @Test
testOnStartedWakingUp_logsUiEvent()1138     public void testOnStartedWakingUp_logsUiEvent() {
1139         final InstanceId instanceId = InstanceId.fakeInstanceId(8);
1140         when(mSessionTracker.getSessionId((anyInt()))).thenReturn(instanceId);
1141         mViewMediator.onStartedWakingUp(PowerManager.WAKE_REASON_LIFT, false);
1142 
1143         verify(mUiEventLogger).logWithInstanceIdAndPosition(
1144                 eq(BiometricUnlockController.BiometricUiEvent.STARTED_WAKING_UP),
1145                 anyInt(),
1146                 any(),
1147                 eq(instanceId),
1148                 eq(PowerManager.WAKE_REASON_LIFT)
1149         );
1150     }
1151 
1152     @Test
1153     @TestableLooper.RunWithLooper(setAsMainLooper = true)
pendingPinLockOnKeyguardGoingAway_doKeyguardLockedOnKeyguardVisibilityChanged()1154     public void pendingPinLockOnKeyguardGoingAway_doKeyguardLockedOnKeyguardVisibilityChanged() {
1155         // GIVEN SIM_STATE_PIN_REQUIRED
1156         mViewMediator.onSystemReady();
1157         final KeyguardUpdateMonitorCallback keyguardUpdateMonitorCallback =
1158                 mViewMediator.mUpdateCallback;
1159         keyguardUpdateMonitorCallback.onSimStateChanged(0, 0,
1160                 TelephonyManager.SIM_STATE_PIN_REQUIRED);
1161         TestableLooper.get(this).processAllMessages();
1162 
1163         // ...and then the primary bouncer shows while the keyguard is going away
1164         captureKeyguardStateControllerCallback();
1165         when(mKeyguardStateController.isPrimaryBouncerShowing()).thenReturn(true);
1166         when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(true);
1167         mKeyguardStateControllerCallback.getValue().onPrimaryBouncerShowingChanged();
1168         TestableLooper.get(this).processAllMessages();
1169 
1170         // WHEN keyguard visibility becomes FALSE
1171         mViewMediator.setShowingLocked(false);
1172         keyguardUpdateMonitorCallback.onKeyguardVisibilityChanged(false);
1173         TestableLooper.get(this).processAllMessages();
1174 
1175         // THEN keyguard shows due to the pending SIM PIN lock
1176         assertTrue(mViewMediator.isShowingAndNotOccluded());
1177     }
1178 
1179     @Test
testBouncerSwipeDown()1180     public void testBouncerSwipeDown() {
1181         mViewMediator.getViewMediatorCallback().onBouncerSwipeDown();
1182         verify(mStatusBarKeyguardViewManager).reset(true);
1183     }
createAndStartViewMediator()1184     private void createAndStartViewMediator() {
1185         createAndStartViewMediator(false);
1186     }
1187 
createAndStartViewMediator(boolean orderUnlockAndWake)1188     private void createAndStartViewMediator(boolean orderUnlockAndWake) {
1189         mContext.getOrCreateTestableResources().addOverride(
1190                 com.android.internal.R.bool.config_orderUnlockAndWake, orderUnlockAndWake);
1191 
1192         mViewMediator = new KeyguardViewMediator(
1193                 mContext,
1194                 mUiEventLogger,
1195                 mSessionTracker,
1196                 mUserTracker,
1197                 mFalsingCollector,
1198                 mLockPatternUtils,
1199                 mBroadcastDispatcher,
1200                 () -> mStatusBarKeyguardViewManager,
1201                 mDismissCallbackRegistry,
1202                 mUpdateMonitor,
1203                 mDumpManager,
1204                 mUiBgExecutor,
1205                 mPowerManager,
1206                 mTrustManager,
1207                 mUserSwitcherController,
1208                 mDeviceConfig,
1209                 mNavigationModeController,
1210                 mKeyguardDisplayManager,
1211                 mDozeParameters,
1212                 mStatusBarStateController,
1213                 mKeyguardStateController,
1214                 () -> mKeyguardUnlockAnimationController,
1215                 mScreenOffAnimationController,
1216                 () -> mNotificationShadeDepthController,
1217                 mScreenOnCoordinator,
1218                 mKeyguardTransitions,
1219                 mKosmos.getInteractionJankMonitor(),
1220                 mDreamOverlayStateController,
1221                 mJavaAdapter,
1222                 mWallpaperRepository,
1223                 () -> mShadeController,
1224                 () -> mNotificationShadeWindowController,
1225                 () -> mActivityTransitionAnimator,
1226                 () -> mScrimController,
1227                 mActivityTaskManagerService,
1228                 mFeatureFlags,
1229                 mSecureSettings,
1230                 mSystemSettings,
1231                 mSystemClock,
1232                 mDispatcher,
1233                 () -> mDreamViewModel,
1234                 () -> mCommunalTransitionViewModel,
1235                 mSystemPropertiesHelper,
1236                 () -> mock(WindowManagerLockscreenVisibilityManager.class),
1237                 mSelectedUserInteractor,
1238                 mKeyguardInteractor,
1239                 mock(WindowManagerOcclusionManager.class));
1240         mViewMediator.start();
1241 
1242         mViewMediator.registerCentralSurfaces(mCentralSurfaces, null, null, null, null);
1243         mViewMediator.onBootCompleted();
1244     }
1245 
captureKeyguardStateControllerCallback()1246     private void captureKeyguardStateControllerCallback() {
1247         verify(mKeyguardStateController).addCallback(mKeyguardStateControllerCallback.capture());
1248     }
1249 
captureKeyguardUpdateMonitorCallback()1250     private void captureKeyguardUpdateMonitorCallback() {
1251         verify(mUpdateMonitor).registerCallback(mKeyguardUpdateMonitorCallbackCaptor.capture());
1252     }
1253 }
1254