Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 1 | /* |
| 2 | * Copyright (C) 2018 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.statusbar.phone; |
| 18 | |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 19 | import static org.mockito.ArgumentMatchers.anyBoolean; |
Lucas Dupin | 71dd484 | 2018-05-29 15:41:03 -0700 | [diff] [blame] | 20 | import static org.mockito.ArgumentMatchers.anyFloat; |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 21 | import static org.mockito.ArgumentMatchers.eq; |
Lucas Dupin | 5431a92 | 2019-07-03 14:29:37 -0700 | [diff] [blame] | 22 | import static org.mockito.Mockito.RETURNS_DEEP_STUBS; |
Lucas Dupin | e9e7071 | 2019-05-01 14:41:49 -0700 | [diff] [blame] | 23 | import static org.mockito.Mockito.clearInvocations; |
Lucas Dupin | 2e838ac | 2019-04-17 16:50:58 -0700 | [diff] [blame] | 24 | import static org.mockito.Mockito.mock; |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 25 | import static org.mockito.Mockito.never; |
| 26 | import static org.mockito.Mockito.reset; |
| 27 | import static org.mockito.Mockito.verify; |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 28 | import static org.mockito.Mockito.when; |
| 29 | |
| 30 | import android.content.Context; |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 31 | import android.testing.AndroidTestingRunner; |
| 32 | import android.testing.TestableLooper; |
Selim Cinek | 06c12d6 | 2019-07-01 19:44:18 -0700 | [diff] [blame] | 33 | import android.view.View; |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 34 | import android.view.ViewGroup; |
Lucas Dupin | 5431a92 | 2019-07-03 14:29:37 -0700 | [diff] [blame] | 35 | import android.view.ViewPropertyAnimator; |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 36 | |
Brett Chabot | 84151d9 | 2019-02-27 15:37:59 -0800 | [diff] [blame] | 37 | import androidx.test.filters.SmallTest; |
| 38 | |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 39 | import com.android.internal.widget.LockPatternUtils; |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 40 | import com.android.keyguard.ViewMediatorCallback; |
| 41 | import com.android.systemui.SysuiTestCase; |
Dave Mankoff | 781ef7e | 2019-06-28 16:33:25 -0400 | [diff] [blame] | 42 | import com.android.systemui.classifier.FalsingManagerFake; |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 43 | import com.android.systemui.keyguard.DismissCallbackRegistry; |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 44 | import com.android.systemui.plugins.ActivityStarter.OnDismissAction; |
Dave Mankoff | 781ef7e | 2019-06-28 16:33:25 -0400 | [diff] [blame] | 45 | import com.android.systemui.plugins.FalsingManager; |
Lucas Dupin | 2e838ac | 2019-04-17 16:50:58 -0700 | [diff] [blame] | 46 | import com.android.systemui.plugins.statusbar.StatusBarStateController; |
Selim Cinek | 06c12d6 | 2019-07-01 19:44:18 -0700 | [diff] [blame] | 47 | import com.android.systemui.statusbar.SysuiStatusBarStateController; |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 48 | |
| 49 | import org.junit.Before; |
| 50 | import org.junit.Test; |
| 51 | import org.junit.runner.RunWith; |
| 52 | import org.mockito.Mock; |
| 53 | import org.mockito.MockitoAnnotations; |
| 54 | |
| 55 | @SmallTest |
| 56 | @RunWith(AndroidTestingRunner.class) |
| 57 | @TestableLooper.RunWithLooper |
| 58 | public class StatusBarKeyguardViewManagerTest extends SysuiTestCase { |
| 59 | |
| 60 | @Mock |
| 61 | private ViewMediatorCallback mViewMediatorCallback; |
| 62 | @Mock |
| 63 | private LockPatternUtils mLockPatternUtils; |
| 64 | @Mock |
| 65 | private KeyguardBouncer mBouncer; |
| 66 | @Mock |
| 67 | private StatusBar mStatusBar; |
| 68 | @Mock |
| 69 | private ViewGroup mContainer; |
| 70 | @Mock |
| 71 | private NotificationPanelView mNotificationPanelView; |
| 72 | @Mock |
Gilad Bretter | cb51b8b | 2018-03-22 17:04:51 +0200 | [diff] [blame] | 73 | private BiometricUnlockController mBiometrucUnlockController; |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 74 | @Mock |
| 75 | private DismissCallbackRegistry mDismissCallbackRegistry; |
Lucas Dupin | 2e838ac | 2019-04-17 16:50:58 -0700 | [diff] [blame] | 76 | @Mock |
| 77 | private ViewGroup mLockIconContainer; |
| 78 | @Mock |
Selim Cinek | 06c12d6 | 2019-07-01 19:44:18 -0700 | [diff] [blame] | 79 | private SysuiStatusBarStateController mStatusBarStateController; |
| 80 | @Mock |
| 81 | private View mNotificationContainer; |
| 82 | @Mock |
| 83 | private KeyguardBypassController mBypassController; |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 84 | private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager; |
| 85 | |
| 86 | @Before |
| 87 | public void setUp() { |
| 88 | MockitoAnnotations.initMocks(this); |
Lucas Dupin | 1a8588d | 2018-08-21 12:18:47 -0700 | [diff] [blame] | 89 | mDependency.injectMockDependency(StatusBarWindowController.class); |
Lucas Dupin | 2e838ac | 2019-04-17 16:50:58 -0700 | [diff] [blame] | 90 | mDependency.injectTestDependency(StatusBarStateController.class, mStatusBarStateController); |
| 91 | when(mLockIconContainer.getParent()).thenReturn(mock(ViewGroup.class)); |
Lucas Dupin | 5431a92 | 2019-07-03 14:29:37 -0700 | [diff] [blame] | 92 | when(mLockIconContainer.animate()).thenReturn(mock(ViewPropertyAnimator.class, |
| 93 | RETURNS_DEEP_STUBS)); |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 94 | mStatusBarKeyguardViewManager = new TestableStatusBarKeyguardViewManager(getContext(), |
| 95 | mViewMediatorCallback, mLockPatternUtils); |
| 96 | mStatusBarKeyguardViewManager.registerStatusBar(mStatusBar, mContainer, |
Lucas Dupin | 2e838ac | 2019-04-17 16:50:58 -0700 | [diff] [blame] | 97 | mNotificationPanelView, mBiometrucUnlockController, mDismissCallbackRegistry, |
Dave Mankoff | 781ef7e | 2019-06-28 16:33:25 -0400 | [diff] [blame] | 98 | mLockIconContainer, mNotificationContainer, mBypassController, |
| 99 | new FalsingManagerFake()); |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 100 | mStatusBarKeyguardViewManager.show(null); |
| 101 | } |
| 102 | |
| 103 | @Test |
| 104 | public void dismissWithAction_AfterKeyguardGoneSetToFalse() { |
Jason Monk | 297c04e | 2018-08-23 17:16:59 -0400 | [diff] [blame] | 105 | OnDismissAction action = () -> false; |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 106 | Runnable cancelAction = () -> {}; |
| 107 | mStatusBarKeyguardViewManager.dismissWithAction(action, cancelAction, |
| 108 | false /* afterKeyguardGone */); |
| 109 | verify(mBouncer).showWithDismissAction(eq(action), eq(cancelAction)); |
| 110 | } |
| 111 | |
| 112 | @Test |
| 113 | public void showBouncer_onlyWhenShowing() { |
| 114 | mStatusBarKeyguardViewManager.hide(0 /* startTime */, 0 /* fadeoutDuration */); |
| 115 | mStatusBar.showBouncer(true /* scrimmed */); |
| 116 | verify(mBouncer, never()).show(anyBoolean(), anyBoolean()); |
| 117 | verify(mBouncer, never()).show(anyBoolean()); |
| 118 | } |
| 119 | |
| 120 | @Test |
| 121 | public void showBouncer_notWhenBouncerAlreadyShowing() { |
| 122 | mStatusBarKeyguardViewManager.hide(0 /* startTime */, 0 /* fadeoutDuration */); |
| 123 | when(mBouncer.isSecure()).thenReturn(true); |
| 124 | mStatusBar.showBouncer(true /* scrimmed */); |
| 125 | verify(mBouncer, never()).show(anyBoolean(), anyBoolean()); |
| 126 | verify(mBouncer, never()).show(anyBoolean()); |
| 127 | } |
| 128 | |
| 129 | @Test |
| 130 | public void showBouncer_showsTheBouncer() { |
| 131 | mStatusBarKeyguardViewManager.showBouncer(true /* scrimmed */); |
| 132 | verify(mBouncer).show(anyBoolean(), eq(true)); |
| 133 | } |
| 134 | |
| 135 | @Test |
| 136 | public void onPanelExpansionChanged_neverHidesFullscreenBouncer() { |
| 137 | // TODO: StatusBar should not be here, mBouncer.isFullscreenBouncer() should do the same. |
| 138 | when(mStatusBar.isFullScreenUserSwitcherState()).thenReturn(true); |
| 139 | mStatusBarKeyguardViewManager.onPanelExpansionChanged(0.5f /* expansion */, |
| 140 | true /* tracking */); |
| 141 | verify(mBouncer).setExpansion(eq(KeyguardBouncer.EXPANSION_VISIBLE)); |
| 142 | } |
| 143 | |
| 144 | @Test |
| 145 | public void onPanelExpansionChanged_neverHidesScrimmedBouncer() { |
Lucas Dupin | 93f714d | 2019-03-26 16:49:24 -0700 | [diff] [blame] | 146 | when(mBouncer.isShowing()).thenReturn(true); |
| 147 | when(mBouncer.isScrimmed()).thenReturn(true); |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 148 | mStatusBarKeyguardViewManager.onPanelExpansionChanged(0.5f /* expansion */, |
| 149 | true /* tracking */); |
| 150 | verify(mBouncer).setExpansion(eq(KeyguardBouncer.EXPANSION_VISIBLE)); |
| 151 | } |
| 152 | |
| 153 | @Test |
| 154 | public void onPanelExpansionChanged_neverShowsDuringHintAnimation() { |
| 155 | when(mNotificationPanelView.isUnlockHintRunning()).thenReturn(true); |
| 156 | mStatusBarKeyguardViewManager.onPanelExpansionChanged(0.5f /* expansion */, |
| 157 | true /* tracking */); |
| 158 | verify(mBouncer).setExpansion(eq(KeyguardBouncer.EXPANSION_HIDDEN)); |
| 159 | } |
| 160 | |
| 161 | @Test |
| 162 | public void onPanelExpansionChanged_propagatesToBouncer() { |
| 163 | mStatusBarKeyguardViewManager.onPanelExpansionChanged(0.5f /* expansion */, |
| 164 | true /* tracking */); |
| 165 | verify(mBouncer).setExpansion(eq(0.5f)); |
| 166 | } |
| 167 | |
| 168 | @Test |
| 169 | public void onPanelExpansionChanged_showsBouncerWhenSwiping() { |
| 170 | when(mStatusBar.isKeyguardCurrentlySecure()).thenReturn(true); |
| 171 | mStatusBarKeyguardViewManager.onPanelExpansionChanged(0.5f /* expansion */, |
| 172 | true /* tracking */); |
| 173 | verify(mBouncer).show(eq(false), eq(false)); |
| 174 | |
| 175 | // But not when it's already visible |
| 176 | reset(mBouncer); |
| 177 | when(mBouncer.isShowing()).thenReturn(true); |
| 178 | mStatusBarKeyguardViewManager.onPanelExpansionChanged(0.5f /* expansion */, true /* tracking */); |
| 179 | verify(mBouncer, never()).show(eq(false), eq(false)); |
| 180 | |
| 181 | // Or animating away |
| 182 | reset(mBouncer); |
| 183 | when(mBouncer.isAnimatingAway()).thenReturn(true); |
| 184 | mStatusBarKeyguardViewManager.onPanelExpansionChanged(0.5f /* expansion */, true /* tracking */); |
| 185 | verify(mBouncer, never()).show(eq(false), eq(false)); |
| 186 | } |
| 187 | |
Lucas Dupin | aece502 | 2018-05-21 16:44:28 -0700 | [diff] [blame] | 188 | @Test |
| 189 | public void onPanelExpansionChanged_neverTranslatesBouncerWhenOccluded() { |
| 190 | mStatusBarKeyguardViewManager.setOccluded(true /* occluded */, false /* animate */); |
| 191 | mStatusBarKeyguardViewManager.onPanelExpansionChanged(0.5f /* expansion */, |
| 192 | true /* tracking */); |
| 193 | verify(mBouncer, never()).setExpansion(eq(0.5f)); |
| 194 | } |
| 195 | |
Lucas Dupin | 71dd484 | 2018-05-29 15:41:03 -0700 | [diff] [blame] | 196 | @Test |
| 197 | public void onPanelExpansionChanged_neverTranslatesBouncerWhenWakeAndUnlock() { |
Gilad Bretter | cb51b8b | 2018-03-22 17:04:51 +0200 | [diff] [blame] | 198 | when(mBiometrucUnlockController.getMode()) |
| 199 | .thenReturn(BiometricUnlockController.MODE_WAKE_AND_UNLOCK); |
Lucas Dupin | 71dd484 | 2018-05-29 15:41:03 -0700 | [diff] [blame] | 200 | mStatusBarKeyguardViewManager.onPanelExpansionChanged(KeyguardBouncer.EXPANSION_VISIBLE, |
| 201 | false /* tracking */); |
| 202 | verify(mBouncer, never()).setExpansion(anyFloat()); |
| 203 | } |
| 204 | |
Lucas Dupin | aaac2cb | 2018-06-08 14:11:41 -0700 | [diff] [blame] | 205 | @Test |
| 206 | public void onPanelExpansionChanged_neverTranslatesBouncerWhenLaunchingApp() { |
| 207 | when(mStatusBar.isInLaunchTransition()).thenReturn(true); |
| 208 | mStatusBarKeyguardViewManager.onPanelExpansionChanged(KeyguardBouncer.EXPANSION_VISIBLE, |
| 209 | false /* tracking */); |
| 210 | verify(mBouncer, never()).setExpansion(anyFloat()); |
| 211 | } |
| 212 | |
Lucas Dupin | e9e7071 | 2019-05-01 14:41:49 -0700 | [diff] [blame] | 213 | @Test |
| 214 | public void setOccluded_animatesPanelExpansion_onlyIfBouncerHidden() { |
| 215 | mStatusBarKeyguardViewManager.setOccluded(false /* occluded */, true /* animated */); |
| 216 | verify(mStatusBar).animateKeyguardUnoccluding(); |
| 217 | |
| 218 | when(mBouncer.isShowing()).thenReturn(true); |
| 219 | clearInvocations(mStatusBar); |
| 220 | mStatusBarKeyguardViewManager.setOccluded(false /* occluded */, true /* animated */); |
| 221 | verify(mStatusBar, never()).animateKeyguardUnoccluding(); |
| 222 | } |
| 223 | |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 224 | private class TestableStatusBarKeyguardViewManager extends StatusBarKeyguardViewManager { |
| 225 | |
| 226 | public TestableStatusBarKeyguardViewManager(Context context, |
| 227 | ViewMediatorCallback callback, |
| 228 | LockPatternUtils lockPatternUtils) { |
| 229 | super(context, callback, lockPatternUtils); |
| 230 | } |
| 231 | |
| 232 | @Override |
| 233 | public void registerStatusBar(StatusBar statusBar, ViewGroup container, |
| 234 | NotificationPanelView notificationPanelView, |
Gilad Bretter | cb51b8b | 2018-03-22 17:04:51 +0200 | [diff] [blame] | 235 | BiometricUnlockController fingerprintUnlockController, |
Lucas Dupin | 2e838ac | 2019-04-17 16:50:58 -0700 | [diff] [blame] | 236 | DismissCallbackRegistry dismissCallbackRegistry, |
Selim Cinek | 06c12d6 | 2019-07-01 19:44:18 -0700 | [diff] [blame] | 237 | ViewGroup lockIconContainer, View notificationContainer, |
Dave Mankoff | 781ef7e | 2019-06-28 16:33:25 -0400 | [diff] [blame] | 238 | KeyguardBypassController bypassController, FalsingManager falsingManager) { |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 239 | super.registerStatusBar(statusBar, container, notificationPanelView, |
Selim Cinek | 06c12d6 | 2019-07-01 19:44:18 -0700 | [diff] [blame] | 240 | fingerprintUnlockController, dismissCallbackRegistry, lockIconContainer, |
Dave Mankoff | 781ef7e | 2019-06-28 16:33:25 -0400 | [diff] [blame] | 241 | notificationContainer, bypassController, falsingManager); |
Lucas Dupin | f9ca35e | 2018-05-16 20:41:35 -0700 | [diff] [blame] | 242 | mBouncer = StatusBarKeyguardViewManagerTest.this.mBouncer; |
| 243 | } |
| 244 | } |
Dave Mankoff | 781ef7e | 2019-06-28 16:33:25 -0400 | [diff] [blame] | 245 | } |