Loading packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +76 −27 Original line number Diff line number Diff line Loading @@ -325,6 +325,8 @@ public class KeyguardViewMediator implements CoreStartable, private static final int UNOCCLUDE_ANIMATION_DURATION = 250; private static final int NO_KEYGUARD_DONE_PENDING = -10000; /** * How far down to animate the unoccluding activity, in terms of percent of the activity's * height. Loading Loading @@ -472,6 +474,8 @@ public class KeyguardViewMediator implements CoreStartable, private boolean mDeviceInteractive; private boolean mGoingToSleep; private final Object mDismissToken = new Object(); // last known state of the cellular connection private final String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE; Loading Loading @@ -502,7 +506,7 @@ public class KeyguardViewMediator implements CoreStartable, private boolean mWaitingUntilKeyguardVisible = false; private final LockPatternUtils mLockPatternUtils; private final BroadcastDispatcher mBroadcastDispatcher; private boolean mKeyguardDonePending = false; private int mKeyguardDonePendingForUser = NO_KEYGUARD_DONE_PENDING; private boolean mUnlockingAndWakingFromDream = false; private boolean mHideAnimationRun = false; private boolean mHideAnimationRunning = false; Loading Loading @@ -667,7 +671,9 @@ public class KeyguardViewMediator implements CoreStartable, void handleBeforeUserSwitching(int userId, Runnable resultCallback) { Log.d(TAG, String.format("onBeforeUserSwitching %d", userId)); synchronized (KeyguardViewMediator.this) { mHandler.removeCallbacksAndMessages(mDismissToken); mHandler.removeMessages(DISMISS); mHandler.removeMessages(HIDE); notifyTrustedChangedLocked(mUpdateMonitor.getUserHasTrust(userId)); resetKeyguardDonePendingLocked(); adjustStatusBarLocked(); Loading Loading @@ -705,7 +711,8 @@ public class KeyguardViewMediator implements CoreStartable, if (mLockPatternUtils.isSecure(userId)) { // We are calling dismiss with a delay as there are race conditions in some scenarios // caused by async layout listeners mHandler.postDelayed(() -> dismiss(null /* callback */, null /* message */), 500); mHandler.postDelayed(() -> dismiss(null /* callback */, null /* message */), mDismissToken, 500); } } Loading Loading @@ -852,6 +859,11 @@ public class KeyguardViewMediator implements CoreStartable, @Override public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType, boolean isStrongBiometric) { if (userId != mSelectedUserInteractor.getSelectedUserId()) { Log.w(TAG, "onBiometricAuthenticated() invoked for userId: " + userId + ", current " + "userId: " + mSelectedUserInteractor.getSelectedUserId()); return; } if (mLockPatternUtils.isSecure(userId)) { mLockPatternUtils.getDevicePolicyManager().reportSuccessfulBiometricAttempt( userId); Loading Loading @@ -891,8 +903,8 @@ public class KeyguardViewMediator implements CoreStartable, if (targetUserId != mSelectedUserInteractor.getSelectedUserId()) { return; } Log.d(TAG, "keyguardDone"); tryKeyguardDone(); Log.d(TAG, "keyguardDone: " + targetUserId); tryKeyguardDone(targetUserId); } @Override Loading @@ -909,18 +921,16 @@ public class KeyguardViewMediator implements CoreStartable, @Override public void keyguardDonePending(int targetUserId) { Trace.beginSection("KeyguardViewMediator.mViewMediatorCallback#keyguardDonePending"); Log.d(TAG, "keyguardDonePending"); Log.d(TAG, "keyguardDonePending: " + targetUserId); if (targetUserId != mSelectedUserInteractor.getSelectedUserId()) { Trace.endSection(); return; } mKeyguardDonePending = true; Trace.beginSection("KeyguardViewMediator.mViewMediatorCallback#keyguardDonePending"); mKeyguardDonePendingForUser = targetUserId; mHideAnimationRun = true; mHideAnimationRunning = true; mKeyguardViewControllerLazy.get() .startPreHideAnimation(mHideAnimationFinishedRunnable); .startPreHideAnimation(new OnHideAnimationFinished(targetUserId)); mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_PENDING_TIMEOUT, KEYGUARD_DONE_PENDING_TIMEOUT_MS); Trace.endSection(); Loading Loading @@ -958,9 +968,10 @@ public class KeyguardViewMediator implements CoreStartable, @Override public void readyForKeyguardDone() { Trace.beginSection("KeyguardViewMediator.mViewMediatorCallback#readyForKeyguardDone"); if (mKeyguardDonePending) { mKeyguardDonePending = false; tryKeyguardDone(); if (mKeyguardDonePendingForUser != NO_KEYGUARD_DONE_PENDING) { int user = mKeyguardDonePendingForUser; mKeyguardDonePendingForUser = NO_KEYGUARD_DONE_PENDING; tryKeyguardDone(user); } Trace.endSection(); } Loading Loading @@ -2672,7 +2683,7 @@ public class KeyguardViewMediator implements CoreStartable, * expecting the keyguard to go away when called. */ public void hideWithAnimation(IRemoteAnimationRunner runner) { if (!mKeyguardDonePending) { if (mKeyguardDonePendingForUser == NO_KEYGUARD_DONE_PENDING) { return; } Loading Loading @@ -2892,10 +2903,17 @@ public class KeyguardViewMediator implements CoreStartable, mTransitionBootInteractor.start(); } private void tryKeyguardDone() { Log.d(TAG, "tryKeyguardDone: pending - " + mKeyguardDonePending + ", animRan - " + mHideAnimationRun + " animRunning - " + mHideAnimationRunning); if (!mKeyguardDonePending && mHideAnimationRun && !mHideAnimationRunning) { private void tryKeyguardDone(int userId) { String logUserId; if (mKeyguardDonePendingForUser == NO_KEYGUARD_DONE_PENDING) { logUserId = "NO_KEYGUARD_DONE_PENDING"; } else { logUserId = "" + mKeyguardDonePendingForUser; } Log.d(TAG, "tryKeyguardDone: pendingForUser - " + logUserId + ", animRan - " + mHideAnimationRun + " animRunning - " + mHideAnimationRunning); if (mKeyguardDonePendingForUser == NO_KEYGUARD_DONE_PENDING && mHideAnimationRun && !mHideAnimationRunning) { handleKeyguardDone(); } else if (mSurfaceBehindRemoteAnimationRunning) { // We're already running the keyguard exit animation, likely due to an in-progress swipe Loading @@ -2906,7 +2924,7 @@ public class KeyguardViewMediator implements CoreStartable, mHideAnimationRun = true; mHideAnimationRunning = true; mKeyguardViewControllerLazy.get() .startPreHideAnimation(mHideAnimationFinishedRunnable); .startPreHideAnimation(new OnHideAnimationFinished(userId)); } } Loading Loading @@ -3180,6 +3198,15 @@ public class KeyguardViewMediator implements CoreStartable, // will be in order. final int keyguardFlag = flags; mUiBgExecutor.execute(() -> { int currentUserId = mSelectedUserInteractor.getSelectedUserId(); if (mGoingAwayRequestedForUserId != currentUserId) { Log.e(TAG, "Not executing goingAwayRunnable() due to userId mismatch. " + "Requested: " + mGoingAwayRequestedForUserId + ", current: " + currentUserId); mUpdateMonitor.setKeyguardGoingAway(false); mKeyguardViewControllerLazy.get().setKeyguardGoingAwayState(false); return; } if (ENABLE_NEW_KEYGUARD_SHELL_TRANSITIONS) { startKeyguardTransition( false /* keyguardShowing */, false /* aodShowing */); Loading @@ -3201,12 +3228,6 @@ public class KeyguardViewMediator implements CoreStartable, mKeyguardTransitions.startKeyguardTransition(keyguardShowing, aodShowing); } private final Runnable mHideAnimationFinishedRunnable = () -> { Log.d(TAG, "mHideAnimationFinishedRunnable#run"); mHideAnimationRunning = false; tryKeyguardDone(); }; private void setUnlockAndWakeFromDream(boolean updatedValue, @WakeAndUnlockUpdateReason int reason) { if (!mOrderUnlockAndWake) { Loading Loading @@ -3329,6 +3350,12 @@ public class KeyguardViewMediator implements CoreStartable, mHiding = false; if (mLockPatternUtils.isSecure(currentUserId)) { doKeyguardLocked(null); if (!KeyguardWmStateRefactor.isEnabled()) { mKeyguardInteractor.showKeyguard(); mShadeController.get().instantCollapseShade(); setShowingLocked(true /* showing */, true /* force */, "handleStartKeyguardExitAnimation - mismatch"); } } else { resetStateLocked(); dismiss(null, null); Loading Loading @@ -3904,7 +3931,7 @@ public class KeyguardViewMediator implements CoreStartable, } private void resetKeyguardDonePendingLocked() { mKeyguardDonePending = false; mKeyguardDonePendingForUser = NO_KEYGUARD_DONE_PENDING; mHandler.removeMessages(KEYGUARD_DONE_PENDING_TIMEOUT); } Loading Loading @@ -4053,7 +4080,7 @@ public class KeyguardViewMediator implements CoreStartable, pw.print(" mDozing: "); pw.println(mDozing); pw.print(" mAodShowing: "); pw.println(mAodShowing); pw.print(" mWaitingUntilKeyguardVisible: "); pw.println(mWaitingUntilKeyguardVisible); pw.print(" mKeyguardDonePending: "); pw.println(mKeyguardDonePending); pw.print(" mKeyguardDonePendingForUser: "); pw.println(mKeyguardDonePendingForUser); pw.print(" mHideAnimationRun: "); pw.println(mHideAnimationRun); pw.print(" mPendingReset: "); pw.println(mPendingReset); pw.print(" mPendingLock: "); pw.println(mPendingLock); Loading Loading @@ -4374,4 +4401,26 @@ public class KeyguardViewMediator implements CoreStartable, mRemoteCallback = remoteCallback; } } private class OnHideAnimationFinished implements Runnable { private final int mUserId; public OnHideAnimationFinished(int userId) { mUserId = userId; } public void run() { Log.d(TAG, "OnHideAnimationFinished.run(" + mUserId + ")"); mHideAnimationRunning = false; int currentUserId = mSelectedUserInteractor.getSelectedUserId(); if (mUserId != currentUserId) { Log.e(TAG, "Not executing OnHideAnimationFinished.run() due to userId mismatch. " + "Requested: " + mUserId + ", current: " + currentUserId); mShadeController.get().instantCollapseShade(); resetStateLocked(); return; } tryKeyguardDone(mUserId); } } } packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +59 −0 Original line number Diff line number Diff line Loading @@ -1413,6 +1413,65 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { assertTrue(mViewMediator.isShowingAndNotOccluded()); } @Test public void biometricAuthSuccessForCurrentUserDoesProceed() { final int currentUser = 25; setCurrentUser(currentUser, true); mViewMediator.mUpdateCallback.onBiometricAuthenticated(currentUser, null, false); verify(mDevicePolicyManager).reportSuccessfulBiometricAttempt(currentUser); } @Test public void biometricAuthSuccessForDifferentUserDoesNotProceed() { final int newUser = 40; setCurrentUser(newUser, true); final int oldUser = 25; mViewMediator.mUpdateCallback.onBiometricAuthenticated(oldUser, null, false); verify(mDevicePolicyManager, never()).reportSuccessfulBiometricAttempt(anyInt()); } @Test public void testDonePendingExecutesOnHideAnimationFinished() { final int currentUser = 25; setCurrentUser(currentUser, true); mViewMediator.mViewMediatorCallback.keyguardDonePending(currentUser); final ArgumentCaptor<Runnable> onHideAnimationFinished = ArgumentCaptor.forClass(Runnable.class); verify(mStatusBarKeyguardViewManager).startPreHideAnimation( onHideAnimationFinished.capture()); onHideAnimationFinished.getValue().run(); // This is executed when the user is incorrect. Should not be called verify(mShadeController, never()).instantCollapseShade(); } @Test public void testDonePendingExecutesOnHideAnimationFinishedButTerminatesWhenUserHasChanged() { final int currentUser = 25; setCurrentUser(currentUser, true); mViewMediator.mViewMediatorCallback.keyguardDonePending(currentUser); final ArgumentCaptor<Runnable> onHideAnimationFinished = ArgumentCaptor.forClass(Runnable.class); verify(mStatusBarKeyguardViewManager).startPreHideAnimation( onHideAnimationFinished.capture()); // User switched before runnable could execute final int newUser = 40; setCurrentUser(newUser, true); onHideAnimationFinished.getValue().run(); // This is executed when the user is incorrect verify(mShadeController).instantCollapseShade(); } @Test public void testBouncerSwipeDown() { mViewMediator.getViewMediatorCallback().onBouncerSwipeDown(); Loading Loading
packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java +76 −27 Original line number Diff line number Diff line Loading @@ -325,6 +325,8 @@ public class KeyguardViewMediator implements CoreStartable, private static final int UNOCCLUDE_ANIMATION_DURATION = 250; private static final int NO_KEYGUARD_DONE_PENDING = -10000; /** * How far down to animate the unoccluding activity, in terms of percent of the activity's * height. Loading Loading @@ -472,6 +474,8 @@ public class KeyguardViewMediator implements CoreStartable, private boolean mDeviceInteractive; private boolean mGoingToSleep; private final Object mDismissToken = new Object(); // last known state of the cellular connection private final String mPhoneState = TelephonyManager.EXTRA_STATE_IDLE; Loading Loading @@ -502,7 +506,7 @@ public class KeyguardViewMediator implements CoreStartable, private boolean mWaitingUntilKeyguardVisible = false; private final LockPatternUtils mLockPatternUtils; private final BroadcastDispatcher mBroadcastDispatcher; private boolean mKeyguardDonePending = false; private int mKeyguardDonePendingForUser = NO_KEYGUARD_DONE_PENDING; private boolean mUnlockingAndWakingFromDream = false; private boolean mHideAnimationRun = false; private boolean mHideAnimationRunning = false; Loading Loading @@ -667,7 +671,9 @@ public class KeyguardViewMediator implements CoreStartable, void handleBeforeUserSwitching(int userId, Runnable resultCallback) { Log.d(TAG, String.format("onBeforeUserSwitching %d", userId)); synchronized (KeyguardViewMediator.this) { mHandler.removeCallbacksAndMessages(mDismissToken); mHandler.removeMessages(DISMISS); mHandler.removeMessages(HIDE); notifyTrustedChangedLocked(mUpdateMonitor.getUserHasTrust(userId)); resetKeyguardDonePendingLocked(); adjustStatusBarLocked(); Loading Loading @@ -705,7 +711,8 @@ public class KeyguardViewMediator implements CoreStartable, if (mLockPatternUtils.isSecure(userId)) { // We are calling dismiss with a delay as there are race conditions in some scenarios // caused by async layout listeners mHandler.postDelayed(() -> dismiss(null /* callback */, null /* message */), 500); mHandler.postDelayed(() -> dismiss(null /* callback */, null /* message */), mDismissToken, 500); } } Loading Loading @@ -852,6 +859,11 @@ public class KeyguardViewMediator implements CoreStartable, @Override public void onBiometricAuthenticated(int userId, BiometricSourceType biometricSourceType, boolean isStrongBiometric) { if (userId != mSelectedUserInteractor.getSelectedUserId()) { Log.w(TAG, "onBiometricAuthenticated() invoked for userId: " + userId + ", current " + "userId: " + mSelectedUserInteractor.getSelectedUserId()); return; } if (mLockPatternUtils.isSecure(userId)) { mLockPatternUtils.getDevicePolicyManager().reportSuccessfulBiometricAttempt( userId); Loading Loading @@ -891,8 +903,8 @@ public class KeyguardViewMediator implements CoreStartable, if (targetUserId != mSelectedUserInteractor.getSelectedUserId()) { return; } Log.d(TAG, "keyguardDone"); tryKeyguardDone(); Log.d(TAG, "keyguardDone: " + targetUserId); tryKeyguardDone(targetUserId); } @Override Loading @@ -909,18 +921,16 @@ public class KeyguardViewMediator implements CoreStartable, @Override public void keyguardDonePending(int targetUserId) { Trace.beginSection("KeyguardViewMediator.mViewMediatorCallback#keyguardDonePending"); Log.d(TAG, "keyguardDonePending"); Log.d(TAG, "keyguardDonePending: " + targetUserId); if (targetUserId != mSelectedUserInteractor.getSelectedUserId()) { Trace.endSection(); return; } mKeyguardDonePending = true; Trace.beginSection("KeyguardViewMediator.mViewMediatorCallback#keyguardDonePending"); mKeyguardDonePendingForUser = targetUserId; mHideAnimationRun = true; mHideAnimationRunning = true; mKeyguardViewControllerLazy.get() .startPreHideAnimation(mHideAnimationFinishedRunnable); .startPreHideAnimation(new OnHideAnimationFinished(targetUserId)); mHandler.sendEmptyMessageDelayed(KEYGUARD_DONE_PENDING_TIMEOUT, KEYGUARD_DONE_PENDING_TIMEOUT_MS); Trace.endSection(); Loading Loading @@ -958,9 +968,10 @@ public class KeyguardViewMediator implements CoreStartable, @Override public void readyForKeyguardDone() { Trace.beginSection("KeyguardViewMediator.mViewMediatorCallback#readyForKeyguardDone"); if (mKeyguardDonePending) { mKeyguardDonePending = false; tryKeyguardDone(); if (mKeyguardDonePendingForUser != NO_KEYGUARD_DONE_PENDING) { int user = mKeyguardDonePendingForUser; mKeyguardDonePendingForUser = NO_KEYGUARD_DONE_PENDING; tryKeyguardDone(user); } Trace.endSection(); } Loading Loading @@ -2672,7 +2683,7 @@ public class KeyguardViewMediator implements CoreStartable, * expecting the keyguard to go away when called. */ public void hideWithAnimation(IRemoteAnimationRunner runner) { if (!mKeyguardDonePending) { if (mKeyguardDonePendingForUser == NO_KEYGUARD_DONE_PENDING) { return; } Loading Loading @@ -2892,10 +2903,17 @@ public class KeyguardViewMediator implements CoreStartable, mTransitionBootInteractor.start(); } private void tryKeyguardDone() { Log.d(TAG, "tryKeyguardDone: pending - " + mKeyguardDonePending + ", animRan - " + mHideAnimationRun + " animRunning - " + mHideAnimationRunning); if (!mKeyguardDonePending && mHideAnimationRun && !mHideAnimationRunning) { private void tryKeyguardDone(int userId) { String logUserId; if (mKeyguardDonePendingForUser == NO_KEYGUARD_DONE_PENDING) { logUserId = "NO_KEYGUARD_DONE_PENDING"; } else { logUserId = "" + mKeyguardDonePendingForUser; } Log.d(TAG, "tryKeyguardDone: pendingForUser - " + logUserId + ", animRan - " + mHideAnimationRun + " animRunning - " + mHideAnimationRunning); if (mKeyguardDonePendingForUser == NO_KEYGUARD_DONE_PENDING && mHideAnimationRun && !mHideAnimationRunning) { handleKeyguardDone(); } else if (mSurfaceBehindRemoteAnimationRunning) { // We're already running the keyguard exit animation, likely due to an in-progress swipe Loading @@ -2906,7 +2924,7 @@ public class KeyguardViewMediator implements CoreStartable, mHideAnimationRun = true; mHideAnimationRunning = true; mKeyguardViewControllerLazy.get() .startPreHideAnimation(mHideAnimationFinishedRunnable); .startPreHideAnimation(new OnHideAnimationFinished(userId)); } } Loading Loading @@ -3180,6 +3198,15 @@ public class KeyguardViewMediator implements CoreStartable, // will be in order. final int keyguardFlag = flags; mUiBgExecutor.execute(() -> { int currentUserId = mSelectedUserInteractor.getSelectedUserId(); if (mGoingAwayRequestedForUserId != currentUserId) { Log.e(TAG, "Not executing goingAwayRunnable() due to userId mismatch. " + "Requested: " + mGoingAwayRequestedForUserId + ", current: " + currentUserId); mUpdateMonitor.setKeyguardGoingAway(false); mKeyguardViewControllerLazy.get().setKeyguardGoingAwayState(false); return; } if (ENABLE_NEW_KEYGUARD_SHELL_TRANSITIONS) { startKeyguardTransition( false /* keyguardShowing */, false /* aodShowing */); Loading @@ -3201,12 +3228,6 @@ public class KeyguardViewMediator implements CoreStartable, mKeyguardTransitions.startKeyguardTransition(keyguardShowing, aodShowing); } private final Runnable mHideAnimationFinishedRunnable = () -> { Log.d(TAG, "mHideAnimationFinishedRunnable#run"); mHideAnimationRunning = false; tryKeyguardDone(); }; private void setUnlockAndWakeFromDream(boolean updatedValue, @WakeAndUnlockUpdateReason int reason) { if (!mOrderUnlockAndWake) { Loading Loading @@ -3329,6 +3350,12 @@ public class KeyguardViewMediator implements CoreStartable, mHiding = false; if (mLockPatternUtils.isSecure(currentUserId)) { doKeyguardLocked(null); if (!KeyguardWmStateRefactor.isEnabled()) { mKeyguardInteractor.showKeyguard(); mShadeController.get().instantCollapseShade(); setShowingLocked(true /* showing */, true /* force */, "handleStartKeyguardExitAnimation - mismatch"); } } else { resetStateLocked(); dismiss(null, null); Loading Loading @@ -3904,7 +3931,7 @@ public class KeyguardViewMediator implements CoreStartable, } private void resetKeyguardDonePendingLocked() { mKeyguardDonePending = false; mKeyguardDonePendingForUser = NO_KEYGUARD_DONE_PENDING; mHandler.removeMessages(KEYGUARD_DONE_PENDING_TIMEOUT); } Loading Loading @@ -4053,7 +4080,7 @@ public class KeyguardViewMediator implements CoreStartable, pw.print(" mDozing: "); pw.println(mDozing); pw.print(" mAodShowing: "); pw.println(mAodShowing); pw.print(" mWaitingUntilKeyguardVisible: "); pw.println(mWaitingUntilKeyguardVisible); pw.print(" mKeyguardDonePending: "); pw.println(mKeyguardDonePending); pw.print(" mKeyguardDonePendingForUser: "); pw.println(mKeyguardDonePendingForUser); pw.print(" mHideAnimationRun: "); pw.println(mHideAnimationRun); pw.print(" mPendingReset: "); pw.println(mPendingReset); pw.print(" mPendingLock: "); pw.println(mPendingLock); Loading Loading @@ -4374,4 +4401,26 @@ public class KeyguardViewMediator implements CoreStartable, mRemoteCallback = remoteCallback; } } private class OnHideAnimationFinished implements Runnable { private final int mUserId; public OnHideAnimationFinished(int userId) { mUserId = userId; } public void run() { Log.d(TAG, "OnHideAnimationFinished.run(" + mUserId + ")"); mHideAnimationRunning = false; int currentUserId = mSelectedUserInteractor.getSelectedUserId(); if (mUserId != currentUserId) { Log.e(TAG, "Not executing OnHideAnimationFinished.run() due to userId mismatch. " + "Requested: " + mUserId + ", current: " + currentUserId); mShadeController.get().instantCollapseShade(); resetStateLocked(); return; } tryKeyguardDone(mUserId); } } }
packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardViewMediatorTest.java +59 −0 Original line number Diff line number Diff line Loading @@ -1413,6 +1413,65 @@ public class KeyguardViewMediatorTest extends SysuiTestCase { assertTrue(mViewMediator.isShowingAndNotOccluded()); } @Test public void biometricAuthSuccessForCurrentUserDoesProceed() { final int currentUser = 25; setCurrentUser(currentUser, true); mViewMediator.mUpdateCallback.onBiometricAuthenticated(currentUser, null, false); verify(mDevicePolicyManager).reportSuccessfulBiometricAttempt(currentUser); } @Test public void biometricAuthSuccessForDifferentUserDoesNotProceed() { final int newUser = 40; setCurrentUser(newUser, true); final int oldUser = 25; mViewMediator.mUpdateCallback.onBiometricAuthenticated(oldUser, null, false); verify(mDevicePolicyManager, never()).reportSuccessfulBiometricAttempt(anyInt()); } @Test public void testDonePendingExecutesOnHideAnimationFinished() { final int currentUser = 25; setCurrentUser(currentUser, true); mViewMediator.mViewMediatorCallback.keyguardDonePending(currentUser); final ArgumentCaptor<Runnable> onHideAnimationFinished = ArgumentCaptor.forClass(Runnable.class); verify(mStatusBarKeyguardViewManager).startPreHideAnimation( onHideAnimationFinished.capture()); onHideAnimationFinished.getValue().run(); // This is executed when the user is incorrect. Should not be called verify(mShadeController, never()).instantCollapseShade(); } @Test public void testDonePendingExecutesOnHideAnimationFinishedButTerminatesWhenUserHasChanged() { final int currentUser = 25; setCurrentUser(currentUser, true); mViewMediator.mViewMediatorCallback.keyguardDonePending(currentUser); final ArgumentCaptor<Runnable> onHideAnimationFinished = ArgumentCaptor.forClass(Runnable.class); verify(mStatusBarKeyguardViewManager).startPreHideAnimation( onHideAnimationFinished.capture()); // User switched before runnable could execute final int newUser = 40; setCurrentUser(newUser, true); onHideAnimationFinished.getValue().run(); // This is executed when the user is incorrect verify(mShadeController).instantCollapseShade(); } @Test public void testBouncerSwipeDown() { mViewMediator.getViewMediatorCallback().onBouncerSwipeDown(); Loading