• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.TestableLooper;
29 
30 import androidx.test.ext.junit.runners.AndroidJUnit4;
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.systemui.keyguard.domain.interactor.KeyguardInteractor;
37 import com.android.keyguard.logging.KeyguardUpdateMonitorLogger;
38 import com.android.systemui.SysuiTestCase;
39 import com.android.systemui.dump.DumpManager;
40 import com.android.systemui.flags.FeatureFlags;
41 import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
42 import com.android.systemui.user.domain.interactor.SelectedUserInteractor;
43 
44 import dagger.Lazy;
45 
46 import org.junit.Before;
47 import org.junit.Test;
48 import org.junit.runner.RunWith;
49 import org.mockito.ArgumentCaptor;
50 import org.mockito.Captor;
51 import org.mockito.Mock;
52 import org.mockito.MockitoAnnotations;
53 
54 import java.util.Random;
55 
56 @SmallTest
57 @TestableLooper.RunWithLooper
58 @RunWith(AndroidJUnit4.class)
59 public class KeyguardStateControllerTest extends SysuiTestCase {
60 
61     @Mock
62     private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
63     @Mock
64     private LockPatternUtils mLockPatternUtils;
65     private KeyguardStateController mKeyguardStateController;
66     @Mock
67     private DumpManager mDumpManager;
68     @Mock
69     private Lazy<KeyguardUnlockAnimationController> mKeyguardUnlockAnimationControllerLazy;
70     @Mock
71     private Lazy<KeyguardInteractor> mKeyguardInteractorLazy;
72     @Mock
73     private SelectedUserInteractor mSelectedUserInteractor;
74     @Mock
75     private KeyguardUpdateMonitorLogger mLogger;
76     @Mock
77     private FeatureFlags mFeatureFlags;
78 
79     @Captor
80     private ArgumentCaptor<KeyguardUpdateMonitorCallback> mUpdateCallbackCaptor;
81 
82     @Before
setup()83     public void setup() {
84         MockitoAnnotations.initMocks(this);
85         mKeyguardStateController = new KeyguardStateControllerImpl(
86                 mContext,
87                 mKeyguardUpdateMonitor,
88                 mLockPatternUtils,
89                 mKeyguardUnlockAnimationControllerLazy,
90                 mLogger,
91                 mDumpManager,
92                 mKeyguardInteractorLazy,
93                 mFeatureFlags,
94                 mSelectedUserInteractor);
95     }
96 
97     @Test
testAddCallback_registersListener()98     public void testAddCallback_registersListener() {
99         verify(mKeyguardUpdateMonitor).registerCallback(any());
100     }
101 
102     @Test
testFaceAuthEnrolleddChanged_calledWhenFaceEnrollmentStateChanges()103     public void testFaceAuthEnrolleddChanged_calledWhenFaceEnrollmentStateChanges() {
104         KeyguardStateController.Callback callback = mock(KeyguardStateController.Callback.class);
105 
106         when(mKeyguardUpdateMonitor.isFaceEnabledAndEnrolled()).thenReturn(false);
107         verify(mKeyguardUpdateMonitor).registerCallback(mUpdateCallbackCaptor.capture());
108         mKeyguardStateController.addCallback(callback);
109         assertThat(mKeyguardStateController.isFaceEnrolledAndEnabled()).isFalse();
110 
111         when(mKeyguardUpdateMonitor.isFaceEnabledAndEnrolled()).thenReturn(true);
112         mUpdateCallbackCaptor.getValue().onBiometricEnrollmentStateChanged(
113                 BiometricSourceType.FACE);
114 
115         assertThat(mKeyguardStateController.isFaceEnrolledAndEnabled()).isTrue();
116         verify(callback).onFaceEnrolledChanged();
117     }
118 
119     @Test
testIsShowing()120     public void testIsShowing() {
121         assertThat(mKeyguardStateController.isShowing()).isFalse();
122         mKeyguardStateController.notifyKeyguardState(true /* showing */, false /* occluded */);
123         assertThat(mKeyguardStateController.isShowing()).isTrue();
124     }
125 
126     @Test
testIsMethodSecure()127     public void testIsMethodSecure() {
128         assertThat(mKeyguardStateController.isMethodSecure()).isFalse();
129 
130         when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
131         ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */);
132         assertThat(mKeyguardStateController.isMethodSecure()).isTrue();
133     }
134 
135     @Test
testIsOccluded()136     public void testIsOccluded() {
137         assertThat(mKeyguardStateController.isOccluded()).isFalse();
138         mKeyguardStateController.notifyKeyguardState(false /* showing */, true /* occluded */);
139         assertThat(mKeyguardStateController.isOccluded()).isTrue();
140     }
141 
142     @Test
testCanSkipLockScreen()143     public void testCanSkipLockScreen() {
144         // Can skip because LockPatternUtils#isSecure is false
145         assertThat(mKeyguardStateController.canDismissLockScreen()).isTrue();
146 
147         // Cannot skip after there's a password/pin/pattern
148         when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
149         ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */);
150         assertThat(mKeyguardStateController.canDismissLockScreen()).isFalse();
151 
152         // Unless user is authenticated
153         when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(anyInt())).thenReturn(true);
154         ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */);
155         assertThat(mKeyguardStateController.canDismissLockScreen()).isTrue();
156     }
157 
158     @Test
testCanSkipLockScreen_updateCalledOnFacesCleared()159     public void testCanSkipLockScreen_updateCalledOnFacesCleared() {
160         verify(mKeyguardUpdateMonitor).registerCallback(mUpdateCallbackCaptor.capture());
161 
162         // Cannot skip after there's a password/pin/pattern
163         when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
164         ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */);
165         assertThat(mKeyguardStateController.canDismissLockScreen()).isFalse();
166 
167         // Unless user is authenticated
168         when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(anyInt())).thenReturn(true);
169         mUpdateCallbackCaptor.getValue().onFacesCleared();
170         assertThat(mKeyguardStateController.canDismissLockScreen()).isTrue();
171     }
172 
173     @Test
testCanSkipLockScreen_updateCalledOnFingerprintssCleared()174     public void testCanSkipLockScreen_updateCalledOnFingerprintssCleared() {
175         verify(mKeyguardUpdateMonitor).registerCallback(mUpdateCallbackCaptor.capture());
176 
177         // Cannot skip after there's a password/pin/pattern
178         when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
179         ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */);
180         assertThat(mKeyguardStateController.canDismissLockScreen()).isFalse();
181 
182         // Unless user is authenticated
183         when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(anyInt())).thenReturn(true);
184         mUpdateCallbackCaptor.getValue().onFingerprintsCleared();
185         assertThat(mKeyguardStateController.canDismissLockScreen()).isTrue();
186     }
187 
188     @Test
testIsUnlocked()189     public void testIsUnlocked() {
190         // Is unlocked whenever the keyguard is not showing
191         assertThat(mKeyguardStateController.isShowing()).isFalse();
192         assertThat(mKeyguardStateController.isUnlocked()).isTrue();
193 
194         // Unlocked if showing, but insecure
195         mKeyguardStateController.notifyKeyguardState(true /* showing */, false /* occluded */);
196         assertThat(mKeyguardStateController.isUnlocked()).isTrue();
197 
198         // Locked if showing, and requires password
199         when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
200         ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */);
201         assertThat(mKeyguardStateController.isUnlocked()).isFalse();
202 
203         // But unlocked after #getUserCanSkipBouncer allows it
204         when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(anyInt())).thenReturn(true);
205         ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */);
206         assertThat(mKeyguardStateController.isUnlocked()).isTrue();
207     }
208 
209     @Test
testIsTrusted()210     public void testIsTrusted() {
211         assertThat(mKeyguardStateController.isTrusted()).isFalse();
212 
213         when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true);
214         ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */);
215 
216         assertThat(mKeyguardStateController.isTrusted()).isTrue();
217     }
218 
219     @Test
testCallbacksAreInvoked()220     public void testCallbacksAreInvoked() {
221         KeyguardStateController.Callback callback = mock(KeyguardStateController.Callback.class);
222         mKeyguardStateController.addCallback(callback);
223 
224         when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true);
225         ((KeyguardStateControllerImpl) mKeyguardStateController).update(false /* alwaysUpdate */);
226 
227         verify(callback).onUnlockedChanged();
228     }
229 
230     @Test
testKeyguardDismissAmountCallbackInvoked()231     public void testKeyguardDismissAmountCallbackInvoked() {
232         KeyguardStateController.Callback callback = mock(KeyguardStateController.Callback.class);
233         mKeyguardStateController.addCallback(callback);
234 
235         mKeyguardStateController.notifyKeyguardDismissAmountChanged(100f, false);
236 
237         verify(callback).onKeyguardDismissAmountChanged();
238     }
239 
240     @Test
testOnEnabledTrustAgentsChangedCallback()241     public void testOnEnabledTrustAgentsChangedCallback() {
242         final Random random = new Random();
243 
244         verify(mKeyguardUpdateMonitor).registerCallback(mUpdateCallbackCaptor.capture());
245         final KeyguardStateController.Callback stateCallback =
246                 mock(KeyguardStateController.Callback.class);
247         mKeyguardStateController.addCallback(stateCallback);
248 
249         when(mLockPatternUtils.isSecure(anyInt())).thenReturn(true);
250         mUpdateCallbackCaptor.getValue().onEnabledTrustAgentsChanged(random.nextInt());
251         verify(stateCallback).onUnlockedChanged();
252     }
253 }
254