1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.biometrics; 18 19 import static org.junit.Assert.assertFalse; 20 import static org.junit.Assert.assertTrue; 21 import static org.mockito.ArgumentMatchers.any; 22 import static org.mockito.ArgumentMatchers.anyInt; 23 import static org.mockito.Mockito.atLeast; 24 import static org.mockito.Mockito.atLeastOnce; 25 import static org.mockito.Mockito.never; 26 import static org.mockito.Mockito.reset; 27 import static org.mockito.Mockito.verify; 28 import static org.mockito.Mockito.when; 29 30 import android.testing.TestableLooper; 31 import android.view.MotionEvent; 32 33 import androidx.test.ext.junit.runners.AndroidJUnit4; 34 import androidx.test.filters.SmallTest; 35 36 import com.android.systemui.RoboPilotTest; 37 import com.android.systemui.shade.ShadeExpansionListener; 38 import com.android.systemui.statusbar.StatusBarState; 39 40 import org.junit.Test; 41 import org.junit.runner.RunWith; 42 43 @SmallTest 44 @RoboPilotTest 45 @RunWith(AndroidJUnit4.class) 46 47 @TestableLooper.RunWithLooper(setAsMainLooper = true) 48 public class UdfpsKeyguardViewLegacyControllerTest extends 49 UdfpsKeyguardViewLegacyControllerBaseTest { 50 @Override createUdfpsKeyguardViewController()51 public UdfpsKeyguardViewControllerLegacy createUdfpsKeyguardViewController() { 52 return createUdfpsKeyguardViewController(/* useModernBouncer */ false, 53 /* useExpandedOverlay */ false); 54 } 55 56 @Test testShouldPauseAuth_bouncerShowing()57 public void testShouldPauseAuth_bouncerShowing() { 58 mController.onViewAttached(); 59 captureStatusBarStateListeners(); 60 sendStatusBarStateChanged(StatusBarState.KEYGUARD); 61 62 when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(true); 63 when(mStatusBarKeyguardViewManager.primaryBouncerIsOrWillBeShowing()).thenReturn(true); 64 when(mView.getUnpausedAlpha()).thenReturn(0); 65 assertTrue(mController.shouldPauseAuth()); 66 } 67 68 @Test testRegistersExpansionChangedListenerOnAttached()69 public void testRegistersExpansionChangedListenerOnAttached() { 70 mController.onViewAttached(); 71 captureStatusBarExpansionListeners(); 72 } 73 74 @Test testRegistersStatusBarStateListenersOnAttached()75 public void testRegistersStatusBarStateListenersOnAttached() { 76 mController.onViewAttached(); 77 captureStatusBarStateListeners(); 78 } 79 80 @Test testViewControllerQueriesSBStateOnAttached()81 public void testViewControllerQueriesSBStateOnAttached() { 82 mController.onViewAttached(); 83 verify(mStatusBarStateController).getState(); 84 verify(mStatusBarStateController).getDozeAmount(); 85 86 final float dozeAmount = .88f; 87 when(mStatusBarStateController.getState()).thenReturn(StatusBarState.SHADE_LOCKED); 88 when(mStatusBarStateController.getDozeAmount()).thenReturn(dozeAmount); 89 captureStatusBarStateListeners(); 90 91 mController.onViewAttached(); 92 verify(mView, atLeast(1)).setPauseAuth(true); 93 verify(mView).onDozeAmountChanged(dozeAmount, dozeAmount, 94 UdfpsKeyguardViewLegacy.ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN); 95 } 96 97 @Test testListenersUnregisteredOnDetached()98 public void testListenersUnregisteredOnDetached() { 99 mController.onViewAttached(); 100 captureStatusBarStateListeners(); 101 captureStatusBarExpansionListeners(); 102 captureKeyguardStateControllerCallback(); 103 mController.onViewDetached(); 104 105 verify(mStatusBarStateController).removeCallback(mStatusBarStateListener); 106 for (ShadeExpansionListener listener : mExpansionListeners) { 107 verify(mShadeExpansionStateManager).removeExpansionListener(listener); 108 } 109 verify(mKeyguardStateController).removeCallback(mKeyguardStateControllerCallback); 110 } 111 112 @Test testDozeEventsSentToView()113 public void testDozeEventsSentToView() { 114 mController.onViewAttached(); 115 captureStatusBarStateListeners(); 116 117 final float linear = .55f; 118 final float eased = .65f; 119 mStatusBarStateListener.onDozeAmountChanged(linear, eased); 120 121 verify(mView).onDozeAmountChanged(linear, eased, 122 UdfpsKeyguardViewLegacy.ANIMATION_BETWEEN_AOD_AND_LOCKSCREEN); 123 } 124 125 @Test testShouldPauseAuthUnpausedAlpha0()126 public void testShouldPauseAuthUnpausedAlpha0() { 127 mController.onViewAttached(); 128 captureStatusBarStateListeners(); 129 130 when(mView.getUnpausedAlpha()).thenReturn(0); 131 sendStatusBarStateChanged(StatusBarState.KEYGUARD); 132 133 assertTrue(mController.shouldPauseAuth()); 134 } 135 136 @Test testFadeFromDialogSuggestedAlpha()137 public void testFadeFromDialogSuggestedAlpha() { 138 // GIVEN view is attached and status bar expansion is 1f 139 mController.onViewAttached(); 140 captureStatusBarStateListeners(); 141 captureStatusBarExpansionListeners(); 142 updateStatusBarExpansion(1f, true); 143 reset(mView); 144 145 // WHEN dialog suggested alpha is .6f 146 when(mView.getDialogSuggestedAlpha()).thenReturn(.6f); 147 sendStatusBarStateChanged(StatusBarState.KEYGUARD); 148 149 // THEN alpha is updated based on dialog suggested alpha 150 verify(mView).setUnpausedAlpha((int) (.6f * 255)); 151 } 152 153 @Test testShouldNotPauseAuthOnKeyguard()154 public void testShouldNotPauseAuthOnKeyguard() { 155 mController.onViewAttached(); 156 captureStatusBarStateListeners(); 157 158 sendStatusBarStateChanged(StatusBarState.KEYGUARD); 159 160 assertFalse(mController.shouldPauseAuth()); 161 } 162 163 @Test onBiometricAuthenticated_pauseAuth()164 public void onBiometricAuthenticated_pauseAuth() { 165 // GIVEN view is attached and we're on the keyguard (see testShouldNotPauseAuthOnKeyguard) 166 mController.onViewAttached(); 167 captureStatusBarStateListeners(); 168 sendStatusBarStateChanged(StatusBarState.KEYGUARD); 169 170 // WHEN biometric is authenticated 171 captureKeyguardStateControllerCallback(); 172 when(mKeyguardUpdateMonitor.getUserUnlockedWithBiometric(anyInt())).thenReturn(true); 173 mKeyguardStateControllerCallback.onUnlockedChanged(); 174 175 // THEN pause auth 176 assertTrue(mController.shouldPauseAuth()); 177 } 178 179 @Test testShouldPauseAuthIsLaunchTransitionFadingAway()180 public void testShouldPauseAuthIsLaunchTransitionFadingAway() { 181 // GIVEN view is attached and we're on the keyguard (see testShouldNotPauseAuthOnKeyguard) 182 mController.onViewAttached(); 183 captureStatusBarStateListeners(); 184 sendStatusBarStateChanged(StatusBarState.KEYGUARD); 185 186 // WHEN isLaunchTransitionFadingAway=true 187 captureKeyguardStateControllerCallback(); 188 when(mKeyguardStateController.isLaunchTransitionFadingAway()).thenReturn(true); 189 mKeyguardStateControllerCallback.onLaunchTransitionFadingAwayChanged(); 190 191 // THEN pause auth 192 assertTrue(mController.shouldPauseAuth()); 193 } 194 195 @Test testShouldPauseAuthOnShadeLocked()196 public void testShouldPauseAuthOnShadeLocked() { 197 mController.onViewAttached(); 198 captureStatusBarStateListeners(); 199 200 sendStatusBarStateChanged(StatusBarState.SHADE_LOCKED); 201 202 assertTrue(mController.shouldPauseAuth()); 203 } 204 205 @Test testShouldPauseAuthOnShade()206 public void testShouldPauseAuthOnShade() { 207 mController.onViewAttached(); 208 captureStatusBarStateListeners(); 209 210 // WHEN not on keyguard yet (shade = home) 211 sendStatusBarStateChanged(StatusBarState.SHADE); 212 213 // THEN pause auth 214 assertTrue(mController.shouldPauseAuth()); 215 } 216 217 @Test testShouldPauseAuthAnimatingScreenOffFromShade()218 public void testShouldPauseAuthAnimatingScreenOffFromShade() { 219 mController.onViewAttached(); 220 captureStatusBarStateListeners(); 221 222 // WHEN transitioning from home/shade => keyguard + animating screen off 223 mStatusBarStateListener.onStatePreChange(StatusBarState.SHADE, StatusBarState.KEYGUARD); 224 when(mKeyguardViewMediator.isAnimatingScreenOff()).thenReturn(true); 225 226 // THEN pause auth 227 assertTrue(mController.shouldPauseAuth()); 228 } 229 230 @Test testDoNotPauseAuthAnimatingScreenOffFromLS()231 public void testDoNotPauseAuthAnimatingScreenOffFromLS() { 232 mController.onViewAttached(); 233 captureStatusBarStateListeners(); 234 235 // WHEN animating screen off transition from LS => AOD 236 sendStatusBarStateChanged(StatusBarState.KEYGUARD); 237 when(mKeyguardViewMediator.isAnimatingScreenOff()).thenReturn(true); 238 239 // THEN don't pause auth 240 assertFalse(mController.shouldPauseAuth()); 241 } 242 243 @Test testOverrideShouldPauseAuthOnShadeLocked()244 public void testOverrideShouldPauseAuthOnShadeLocked() { 245 mController.onViewAttached(); 246 captureStatusBarStateListeners(); 247 248 sendStatusBarStateChanged(StatusBarState.SHADE_LOCKED); 249 assertTrue(mController.shouldPauseAuth()); 250 } 251 252 @Test testFadeInWithStatusBarExpansion()253 public void testFadeInWithStatusBarExpansion() { 254 // GIVEN view is attached 255 mController.onViewAttached(); 256 captureStatusBarExpansionListeners(); 257 captureKeyguardStateControllerCallback(); 258 reset(mView); 259 260 // WHEN status bar expansion is 0 261 updateStatusBarExpansion(0, true); 262 263 // THEN alpha is 0 264 verify(mView).setUnpausedAlpha(0); 265 } 266 267 @Test testTransitionToFullShadeProgress()268 public void testTransitionToFullShadeProgress() { 269 // GIVEN view is attached and status bar expansion is 1f 270 mController.onViewAttached(); 271 captureStatusBarExpansionListeners(); 272 updateStatusBarExpansion(1f, true); 273 reset(mView); 274 when(mView.getDialogSuggestedAlpha()).thenReturn(1f); 275 276 // WHEN we're transitioning to the full shade 277 float transitionProgress = .6f; 278 mController.setTransitionToFullShadeProgress(transitionProgress); 279 280 // THEN alpha is between 0 and 255 281 verify(mView).setUnpausedAlpha((int) ((1f - transitionProgress) * 255)); 282 } 283 284 @Test testUpdatePanelExpansion_pauseAuth()285 public void testUpdatePanelExpansion_pauseAuth() { 286 // GIVEN view is attached + on the keyguard 287 mController.onViewAttached(); 288 captureStatusBarStateListeners(); 289 captureStatusBarExpansionListeners(); 290 sendStatusBarStateChanged(StatusBarState.KEYGUARD); 291 reset(mView); 292 293 // WHEN panelViewExpansion changes to hide 294 when(mView.getUnpausedAlpha()).thenReturn(0); 295 updateStatusBarExpansion(0f, false); 296 297 // THEN pause auth is updated to PAUSE 298 verify(mView, atLeastOnce()).setPauseAuth(true); 299 } 300 301 @Test testUpdatePanelExpansion_unpauseAuth()302 public void testUpdatePanelExpansion_unpauseAuth() { 303 // GIVEN view is attached + on the keyguard + panel expansion is 0f 304 mController.onViewAttached(); 305 captureStatusBarStateListeners(); 306 captureStatusBarExpansionListeners(); 307 sendStatusBarStateChanged(StatusBarState.KEYGUARD); 308 reset(mView); 309 310 // WHEN panelViewExpansion changes to expanded 311 when(mView.getUnpausedAlpha()).thenReturn(255); 312 updateStatusBarExpansion(1f, true); 313 314 // THEN pause auth is updated to NOT pause 315 verify(mView, atLeastOnce()).setPauseAuth(false); 316 } 317 318 @Test 319 // TODO(b/259264861): Tracking Bug testUdfpsExpandedOverlayOn()320 public void testUdfpsExpandedOverlayOn() { 321 // GIVEN view is attached and useExpandedOverlay is true 322 mController = createUdfpsKeyguardViewController(false, true); 323 mController.onViewAttached(); 324 captureKeyGuardViewManagerCallback(); 325 326 // WHEN a touch is received 327 mKeyguardViewManagerCallback.onTouch( 328 MotionEvent.obtain(0, 0, 0, 0, 0, 0)); 329 330 // THEN udfpsController onTouch is not called 331 assertTrue(mView.mUseExpandedOverlay); 332 verify(mUdfpsController, never()).onTouch(any()); 333 } 334 335 @Test 336 // TODO(b/259264861): Tracking Bug testUdfpsExpandedOverlayOff()337 public void testUdfpsExpandedOverlayOff() { 338 // GIVEN view is attached and useExpandedOverlay is false 339 mController.onViewAttached(); 340 captureKeyGuardViewManagerCallback(); 341 342 // WHEN a touch is received 343 mKeyguardViewManagerCallback.onTouch( 344 MotionEvent.obtain(0, 0, 0, 0, 0, 0)); 345 346 // THEN udfpsController onTouch is called 347 assertFalse(mView.mUseExpandedOverlay); 348 verify(mUdfpsController).onTouch(any()); 349 } 350 } 351