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.statusbar.policy; 18 19 import static com.google.common.truth.Truth.assertThat; 20 21 import static org.mockito.ArgumentMatchers.any; 22 import static org.mockito.ArgumentMatchers.anyInt; 23 import static org.mockito.Mockito.mock; 24 import static org.mockito.Mockito.verify; 25 import static org.mockito.Mockito.when; 26 27 import android.hardware.biometrics.BiometricSourceType; 28 import android.testing.AndroidTestingRunner; 29 import android.testing.TestableLooper; 30 31 import androidx.test.filters.SmallTest; 32 33 import com.android.internal.widget.LockPatternUtils; 34 import com.android.keyguard.KeyguardUpdateMonitor; 35 import com.android.keyguard.KeyguardUpdateMonitorCallback; 36 import com.android.keyguard.logging.KeyguardUpdateMonitorLogger; 37 import com.android.systemui.SysuiTestCase; 38 import com.android.systemui.dump.DumpManager; 39 import com.android.systemui.flags.FeatureFlags; 40 import com.android.systemui.keyguard.KeyguardUnlockAnimationController; 41 42 import dagger.Lazy; 43 44 import org.junit.Before; 45 import org.junit.Test; 46 import org.junit.runner.RunWith; 47 import org.mockito.ArgumentCaptor; 48 import org.mockito.Captor; 49 import org.mockito.Mock; 50 import org.mockito.MockitoAnnotations; 51 52 import java.util.Random; 53 54 55 @SmallTest 56 @TestableLooper.RunWithLooper 57 @RunWith(AndroidTestingRunner.class) 58 public class KeyguardStateControllerTest extends SysuiTestCase { 59 60 @Mock 61 private KeyguardUpdateMonitor mKeyguardUpdateMonitor; 62 @Mock 63 private LockPatternUtils mLockPatternUtils; 64 private KeyguardStateController mKeyguardStateController; 65 @Mock 66 private DumpManager mDumpManager; 67 @Mock 68 private Lazy<KeyguardUnlockAnimationController> mKeyguardUnlockAnimationControllerLazy; 69 @Mock 70 private KeyguardUpdateMonitorLogger mLogger; 71 @Mock 72 private FeatureFlags mFeatureFlags; 73 74 @Captor 75 private ArgumentCaptor<KeyguardUpdateMonitorCallback> mUpdateCallbackCaptor; 76 77 @Before setup()78 public void setup() { 79 MockitoAnnotations.initMocks(this); 80 mKeyguardStateController = new KeyguardStateControllerImpl( 81 mContext, 82 mKeyguardUpdateMonitor, 83 mLockPatternUtils, 84 mKeyguardUnlockAnimationControllerLazy, 85 mLogger, 86 mDumpManager, 87 mFeatureFlags); 88 } 89 90 @Test testAddCallback_registersListener()91 public void testAddCallback_registersListener() { 92 verify(mKeyguardUpdateMonitor).registerCallback(any()); 93 } 94 95 @Test testFaceAuthEnabledChanged_calledWhenFaceEnrollmentStateChanges()96 public void testFaceAuthEnabledChanged_calledWhenFaceEnrollmentStateChanges() { 97 KeyguardStateController.Callback callback = mock(KeyguardStateController.Callback.class); 98 99 when(mKeyguardUpdateMonitor.isFaceAuthEnabledForUser(anyInt())).thenReturn(false); 100 verify(mKeyguardUpdateMonitor).registerCallback(mUpdateCallbackCaptor.capture()); 101 mKeyguardStateController.addCallback(callback); 102 assertThat(mKeyguardStateController.isFaceAuthEnabled()).isFalse(); 103 104 when(mKeyguardUpdateMonitor.isFaceAuthEnabledForUser(anyInt())).thenReturn(true); 105 mUpdateCallbackCaptor.getValue().onBiometricEnrollmentStateChanged( 106 BiometricSourceType.FACE); 107 108 assertThat(mKeyguardStateController.isFaceAuthEnabled()).isTrue(); 109 verify(callback).onFaceAuthEnabledChanged(); 110 } 111 112 @Test testIsShowing()113 public void testIsShowing() { 114 assertThat(mKeyguardStateController.isShowing()).isFalse(); 115 mKeyguardStateController.notifyKeyguardState(true /* showing */, false /* occluded */); 116 assertThat(mKeyguardStateController.isShowing()).isTrue(); 117 } 118 119 @Test testIsMethodSecure()120 public void testIsMethodSecure() { 121 assertThat(mKeyguardStateController.isMethodSecure()).isFalse(); 122 123 when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true); 124 ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */); 125 assertThat(mKeyguardStateController.isMethodSecure()).isTrue(); 126 } 127 128 @Test testIsOccluded()129 public void testIsOccluded() { 130 assertThat(mKeyguardStateController.isOccluded()).isFalse(); 131 mKeyguardStateController.notifyKeyguardState(false /* showing */, true /* occluded */); 132 assertThat(mKeyguardStateController.isOccluded()).isTrue(); 133 } 134 135 @Test testCanSkipLockScreen()136 public void testCanSkipLockScreen() { 137 // Can skip because LockPatternUtils#isSecure is false 138 assertThat(mKeyguardStateController.canDismissLockScreen()).isTrue(); 139 140 // Cannot skip after there's a password/pin/pattern 141 when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true); 142 ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */); 143 assertThat(mKeyguardStateController.canDismissLockScreen()).isFalse(); 144 145 // Unless user is authenticated 146 when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(anyInt())).thenReturn(true); 147 ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */); 148 assertThat(mKeyguardStateController.canDismissLockScreen()).isTrue(); 149 } 150 151 @Test testIsUnlocked()152 public void testIsUnlocked() { 153 // Is unlocked whenever the keyguard is not showing 154 assertThat(mKeyguardStateController.isShowing()).isFalse(); 155 assertThat(mKeyguardStateController.isUnlocked()).isTrue(); 156 157 // Unlocked if showing, but insecure 158 mKeyguardStateController.notifyKeyguardState(true /* showing */, false /* occluded */); 159 assertThat(mKeyguardStateController.isUnlocked()).isTrue(); 160 161 // Locked if showing, and requires password 162 when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true); 163 ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */); 164 assertThat(mKeyguardStateController.isUnlocked()).isFalse(); 165 166 // But unlocked after #getUserCanSkipBouncer allows it 167 when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(anyInt())).thenReturn(true); 168 ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */); 169 assertThat(mKeyguardStateController.isUnlocked()).isTrue(); 170 } 171 172 @Test testIsTrusted()173 public void testIsTrusted() { 174 assertThat(mKeyguardStateController.isTrusted()).isFalse(); 175 176 when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true); 177 ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */); 178 179 assertThat(mKeyguardStateController.isTrusted()).isTrue(); 180 } 181 182 @Test testCallbacksAreInvoked()183 public void testCallbacksAreInvoked() { 184 KeyguardStateController.Callback callback = mock(KeyguardStateController.Callback.class); 185 mKeyguardStateController.addCallback(callback); 186 187 when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true); 188 ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */); 189 190 verify(callback).onUnlockedChanged(); 191 } 192 193 @Test testKeyguardDismissAmountCallbackInvoked()194 public void testKeyguardDismissAmountCallbackInvoked() { 195 KeyguardStateController.Callback callback = mock(KeyguardStateController.Callback.class); 196 mKeyguardStateController.addCallback(callback); 197 198 mKeyguardStateController.notifyKeyguardDismissAmountChanged(100f, false); 199 200 verify(callback).onKeyguardDismissAmountChanged(); 201 } 202 203 @Test testOnEnabledTrustAgentsChangedCallback()204 public void testOnEnabledTrustAgentsChangedCallback() { 205 final Random random = new Random(); 206 207 verify(mKeyguardUpdateMonitor).registerCallback(mUpdateCallbackCaptor.capture()); 208 final KeyguardStateController.Callback stateCallback = 209 mock(KeyguardStateController.Callback.class); 210 mKeyguardStateController.addCallback(stateCallback); 211 212 when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true); 213 mUpdateCallbackCaptor.getValue().onEnabledTrustAgentsChanged(random.nextInt()); 214 verify(stateCallback).onUnlockedChanged(); 215 } 216 } 217