blob: 852271aa03821119e8f48b48a563b9e6b0dbd6df [file] [log] [blame]
Lucas Dupin6865b712017-09-11 12:28:03 -07001/*
2 * Copyright (C) 2017 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
17package com.android.systemui.statusbar.phone;
18
Lucas Dupinf9ca35e2018-05-16 20:41:35 -070019import static com.google.common.truth.Truth.assertThat;
20
Lucas Dupin787f9a02019-04-24 14:56:52 -070021import static org.mockito.ArgumentMatchers.any;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070022import static org.mockito.ArgumentMatchers.anyFloat;
23import static org.mockito.ArgumentMatchers.anyInt;
24import static org.mockito.ArgumentMatchers.eq;
Lucas Dupin93f714d2019-03-26 16:49:24 -070025import static org.mockito.Mockito.doAnswer;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070026import static org.mockito.Mockito.never;
27import static org.mockito.Mockito.reset;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070028import static org.mockito.Mockito.verify;
29import static org.mockito.Mockito.verifyNoMoreInteractions;
30import static org.mockito.Mockito.verifyZeroInteractions;
31import static org.mockito.Mockito.when;
32
Jason Monka716bac2018-12-05 15:48:21 -050033import android.content.res.ColorStateList;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070034import android.graphics.Color;
Lucas Dupin787f9a02019-04-24 14:56:52 -070035import android.os.Handler;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070036import android.testing.AndroidTestingRunner;
37import android.testing.TestableLooper;
Lucas Dupin6865b712017-09-11 12:28:03 -070038import android.view.ViewGroup;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070039import android.view.ViewTreeObserver;
Lucas Dupin6865b712017-09-11 12:28:03 -070040import android.widget.FrameLayout;
41
Brett Chabot84151d92019-02-27 15:37:59 -080042import androidx.test.filters.SmallTest;
43
Lucas Dupin6865b712017-09-11 12:28:03 -070044import com.android.internal.widget.LockPatternUtils;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070045import com.android.keyguard.KeyguardHostView;
46import com.android.keyguard.KeyguardSecurityModel;
Lucas Dupin787f9a02019-04-24 14:56:52 -070047import com.android.keyguard.KeyguardUpdateMonitor;
Lucas Dupin6865b712017-09-11 12:28:03 -070048import com.android.keyguard.ViewMediatorCallback;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070049import com.android.systemui.DejankUtils;
Lucas Dupin6865b712017-09-11 12:28:03 -070050import com.android.systemui.SysuiTestCase;
51import com.android.systemui.keyguard.DismissCallbackRegistry;
Jason Monk297c04e2018-08-23 17:16:59 -040052import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
Dave Mankoff468d4f62019-05-08 14:56:29 -040053import com.android.systemui.plugins.FalsingManager;
Lucas Dupin6865b712017-09-11 12:28:03 -070054
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070055import org.junit.Assert;
56import org.junit.Before;
Lucas Dupin6865b712017-09-11 12:28:03 -070057import org.junit.Test;
58import org.junit.runner.RunWith;
Lucas Dupin787f9a02019-04-24 14:56:52 -070059import org.mockito.ArgumentCaptor;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070060import org.mockito.Mock;
61import org.mockito.MockitoAnnotations;
Lucas Dupin6865b712017-09-11 12:28:03 -070062
63@SmallTest
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070064@RunWith(AndroidTestingRunner.class)
Jason Monka716bac2018-12-05 15:48:21 -050065@TestableLooper.RunWithLooper
Lucas Dupin6865b712017-09-11 12:28:03 -070066public class KeyguardBouncerTest extends SysuiTestCase {
67
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070068 @Mock
69 private FalsingManager mFalsingManager;
70 @Mock
71 private ViewMediatorCallback mViewMediatorCallback;
72 @Mock
73 private LockPatternUtils mLockPatternUtils;
74 @Mock
75 private DismissCallbackRegistry mDismissCallbackRegistry;
76 @Mock
77 private KeyguardHostView mKeyguardHostView;
78 @Mock
79 private ViewTreeObserver mViewTreeObserver;
Lucas Dupin15a6b6c2018-04-16 14:50:20 +080080 @Mock
81 private KeyguardBouncer.BouncerExpansionCallback mExpansionCallback;
Lucas Dupin787f9a02019-04-24 14:56:52 -070082 @Mock
83 private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
84 @Mock
Lucas Dupin7825b942019-06-03 20:22:39 -070085 private UnlockMethodCache mUnlockMethodCache;
86 @Mock
Lucas Dupin787f9a02019-04-24 14:56:52 -070087 private Handler mHandler;
Lucas Dupin6865b712017-09-11 12:28:03 -070088
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070089 private KeyguardBouncer mBouncer;
90
91 @Before
92 public void setup() {
Jason Monka716bac2018-12-05 15:48:21 -050093 com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070094 MockitoAnnotations.initMocks(this);
95 DejankUtils.setImmediate(true);
96 final ViewGroup container = new FrameLayout(getContext());
97 when(mKeyguardHostView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
98 when(mKeyguardHostView.getHeight()).thenReturn(500);
99 mBouncer = new KeyguardBouncer(getContext(), mViewMediatorCallback,
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800100 mLockPatternUtils, container, mDismissCallbackRegistry, mFalsingManager,
Lucas Dupin7825b942019-06-03 20:22:39 -0700101 mExpansionCallback, mUnlockMethodCache, mKeyguardUpdateMonitor, mHandler) {
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700102 @Override
103 protected void inflateView() {
104 super.inflateView();
105 mKeyguardView = mKeyguardHostView;
106 }
107 };
Lucas Dupin6865b712017-09-11 12:28:03 -0700108 }
109
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700110 @Test
111 public void testInflateView_doesntCrash() {
112 mBouncer.inflateView();
113 }
114
115 @Test
116 public void testShow_notifiesFalsingManager() {
117 mBouncer.show(true);
118 verify(mFalsingManager).onBouncerShown();
119
120 mBouncer.show(true, false);
121 verifyNoMoreInteractions(mFalsingManager);
122 }
123
124 /**
125 * Regression test: Invisible bouncer when occluded.
126 */
127 @Test
128 public void testShow_bouncerIsVisible() {
129 // Expand notification panel as if we were in the keyguard.
130 mBouncer.ensureView();
131 mBouncer.setExpansion(1);
132
133 reset(mKeyguardHostView);
134 when(mKeyguardHostView.getHeight()).thenReturn(500);
135
136 mBouncer.show(true);
137 verify(mKeyguardHostView).setAlpha(eq(1f));
138 verify(mKeyguardHostView).setTranslationY(eq(0f));
139 }
140
141 @Test
142 public void testShow_notifiesVisibility() {
143 mBouncer.show(true);
144 verify(mViewMediatorCallback).onBouncerVisiblityChanged(eq(true));
Lucas Dupin2e838ac2019-04-17 16:50:58 -0700145 verify(mExpansionCallback).onStartingToShow();
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700146
147 // Not called again when visible
148 reset(mViewMediatorCallback);
149 mBouncer.show(true);
150 verifyNoMoreInteractions(mViewMediatorCallback);
151 }
152
153 @Test
154 public void testShow_triesToDismissKeyguard() {
155 mBouncer.show(true);
156 verify(mKeyguardHostView).dismiss(anyInt());
157 }
158
159 @Test
160 public void testShow_resetsSecuritySelection() {
161 mBouncer.show(false);
Lucas Dupin05726cd2018-03-13 14:00:24 -0700162 verify(mKeyguardHostView, never()).showPrimarySecurityScreen();
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700163
164 mBouncer.hide(false);
165 mBouncer.show(true);
166 verify(mKeyguardHostView).showPrimarySecurityScreen();
167 }
168
169 @Test
170 public void testShow_animatesKeyguardView() {
171 mBouncer.show(true);
172 verify(mKeyguardHostView).startAppearAnimation();
173 }
174
175 @Test
176 public void testShow_showsErrorMessage() {
177 final String errorMessage = "an error message";
178 when(mViewMediatorCallback.consumeCustomMessage()).thenReturn(errorMessage);
179 mBouncer.show(true);
180 verify(mKeyguardHostView).showErrorMessage(eq(errorMessage));
181 }
182
183 @Test
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800184 public void testSetExpansion_notifiesFalsingManager() {
Lucas Dupind2ce46d2018-04-04 17:00:29 -0700185 mBouncer.ensureView();
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800186 mBouncer.setExpansion(0.5f);
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700187
Lucas Dupin84993542018-10-11 19:23:45 -0700188 mBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700189 verify(mFalsingManager).onBouncerHidden();
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800190 verify(mExpansionCallback).onFullyHidden();
191
Lucas Dupin84993542018-10-11 19:23:45 -0700192 mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800193 verify(mFalsingManager).onBouncerShown();
194 verify(mExpansionCallback).onFullyShown();
Lucas Dupin84993542018-10-11 19:23:45 -0700195
196 verify(mExpansionCallback, never()).onStartingToHide();
197 mBouncer.setExpansion(0.9f);
198 verify(mExpansionCallback).onStartingToHide();
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800199 }
200
201 @Test
202 public void testSetExpansion_notifiesKeyguardView() {
203 mBouncer.ensureView();
204 mBouncer.setExpansion(0.1f);
205
206 mBouncer.setExpansion(0);
207 verify(mKeyguardHostView).onResume();
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700208 }
209
210 @Test
211 public void testHide_notifiesFalsingManager() {
212 mBouncer.hide(false);
213 verify(mFalsingManager).onBouncerHidden();
214 }
215
216 @Test
217 public void testHide_notifiesVisibility() {
218 mBouncer.hide(false);
219 verify(mViewMediatorCallback).onBouncerVisiblityChanged(eq(false));
220 }
221
222 @Test
223 public void testHide_notifiesDismissCallbackIfVisible() {
224 mBouncer.hide(false);
225 verifyZeroInteractions(mDismissCallbackRegistry);
226 mBouncer.show(false);
227 mBouncer.hide(false);
228 verify(mDismissCallbackRegistry).notifyDismissCancelled();
229 }
230
231 @Test
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800232 public void testHide_notShowingAnymore() {
233 mBouncer.ensureView();
234 mBouncer.show(false /* resetSecuritySelection */);
235 mBouncer.hide(false /* destroyViews */);
236 Assert.assertFalse("Not showing", mBouncer.isShowing());
237 }
238
239 @Test
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700240 public void testShowPromptReason_propagates() {
241 mBouncer.ensureView();
242 mBouncer.showPromptReason(1);
243 verify(mKeyguardHostView).showPromptReason(eq(1));
244 }
245
246 @Test
247 public void testShowMessage_propagates() {
248 final String message = "a message";
249 mBouncer.ensureView();
Jason Chang1e4a4bd2018-05-22 17:30:19 +0800250 mBouncer.showMessage(message, ColorStateList.valueOf(Color.GREEN));
251 verify(mKeyguardHostView).showMessage(eq(message), eq(ColorStateList.valueOf(Color.GREEN)));
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700252 }
253
254 @Test
255 public void testShowOnDismissAction_showsBouncer() {
Jason Monk297c04e2018-08-23 17:16:59 -0400256 final OnDismissAction dismissAction = () -> false;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700257 final Runnable cancelAction = () -> {};
258 mBouncer.showWithDismissAction(dismissAction, cancelAction);
259 verify(mKeyguardHostView).setOnDismissAction(dismissAction, cancelAction);
260 Assert.assertTrue("Should be showing", mBouncer.isShowing());
261 }
262
263 @Test
264 public void testStartPreHideAnimation_notifiesView() {
265 final boolean[] ran = {false};
266 final Runnable r = () -> ran[0] = true;
267 mBouncer.startPreHideAnimation(r);
268 Assert.assertTrue("Callback should have been invoked", ran[0]);
269
270 ran[0] = false;
271 mBouncer.ensureView();
272 mBouncer.startPreHideAnimation(r);
273 verify(mKeyguardHostView).startDisappearAnimation(r);
274 Assert.assertFalse("Callback should have been deferred", ran[0]);
275 }
276
277 @Test
Lucas Dupin3d565fa2018-03-20 15:40:14 -0700278 public void testIsShowing_animated() {
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700279 Assert.assertFalse("Show wasn't invoked yet", mBouncer.isShowing());
Lucas Dupin3d565fa2018-03-20 15:40:14 -0700280 mBouncer.show(true /* reset */);
281 Assert.assertTrue("Should be showing", mBouncer.isShowing());
282 }
283
284 @Test
285 public void testIsShowing_forSwipeUp() {
286 mBouncer.setExpansion(1f);
287 mBouncer.show(true /* reset */, false /* animated */);
288 Assert.assertFalse("Should only be showing after collapsing notification panel",
289 mBouncer.isShowing());
290 mBouncer.setExpansion(0f);
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700291 Assert.assertTrue("Should be showing", mBouncer.isShowing());
292 }
293
294 @Test
295 public void testSetExpansion() {
296 mBouncer.ensureView();
297 mBouncer.setExpansion(0.5f);
298 verify(mKeyguardHostView).setAlpha(anyFloat());
299 verify(mKeyguardHostView).setTranslationY(anyFloat());
300 }
301
302 @Test
303 public void testNeedsFullscreenBouncer_asksKeyguardView() {
304 mBouncer.ensureView();
305 mBouncer.needsFullscreenBouncer();
306 verify(mKeyguardHostView).getSecurityMode();
307 verify(mKeyguardHostView, never()).getCurrentSecurityMode();
308 }
309
310 @Test
311 public void testIsFullscreenBouncer_asksKeyguardView() {
312 mBouncer.ensureView();
313 mBouncer.isFullscreenBouncer();
314 verify(mKeyguardHostView).getCurrentSecurityMode();
315 verify(mKeyguardHostView, never()).getSecurityMode();
316 }
317
318 @Test
Lucas Dupin28dc9d72018-03-21 15:59:15 -0700319 public void testIsHiding_preHideOrHide() {
320 Assert.assertFalse("Should not be hiding on initial state", mBouncer.isAnimatingAway());
321 mBouncer.startPreHideAnimation(null /* runnable */);
322 Assert.assertTrue("Should be hiding during pre-hide", mBouncer.isAnimatingAway());
323 mBouncer.hide(false /* destroyView */);
324 Assert.assertFalse("Should be hidden after hide()", mBouncer.isAnimatingAway());
325 }
326
327 @Test
328 public void testIsHiding_skipsTranslation() {
329 mBouncer.show(false /* reset */);
330 reset(mKeyguardHostView);
331 mBouncer.startPreHideAnimation(null /* runnable */);
332 mBouncer.setExpansion(0.5f);
333 verify(mKeyguardHostView, never()).setTranslationY(anyFloat());
334 verify(mKeyguardHostView, never()).setAlpha(anyFloat());
335 }
336
337 @Test
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700338 public void testIsSecure() {
339 Assert.assertTrue("Bouncer is secure before inflating views", mBouncer.isSecure());
340
341 mBouncer.ensureView();
342 for (KeyguardSecurityModel.SecurityMode mode : KeyguardSecurityModel.SecurityMode.values()){
343 reset(mKeyguardHostView);
344 when(mKeyguardHostView.getSecurityMode()).thenReturn(mode);
345 Assert.assertEquals("Security doesn't match for mode: " + mode,
346 mBouncer.isSecure(), mode != KeyguardSecurityModel.SecurityMode.None);
347 }
348 }
Lucas Dupin6f0d71f2018-03-23 17:26:06 -0700349
350 @Test
Lucas Dupin93f714d2019-03-26 16:49:24 -0700351 public void testIsShowingScrimmed_true() {
352 doAnswer(invocation -> {
353 assertThat(mBouncer.isScrimmed()).isTrue();
354 return null;
355 }).when(mExpansionCallback).onFullyShown();
Lucas Dupinf9ca35e2018-05-16 20:41:35 -0700356 mBouncer.show(false /* resetSecuritySelection */, true /* animate */);
Lucas Dupin93f714d2019-03-26 16:49:24 -0700357 assertThat(mBouncer.isScrimmed()).isTrue();
358 mBouncer.hide(false /* destroyView */);
359 assertThat(mBouncer.isScrimmed()).isFalse();
360 }
361
362 @Test
363 public void testIsShowingScrimmed_false() {
364 doAnswer(invocation -> {
365 assertThat(mBouncer.isScrimmed()).isFalse();
366 return null;
367 }).when(mExpansionCallback).onFullyShown();
Lucas Dupinf9ca35e2018-05-16 20:41:35 -0700368 mBouncer.show(false /* resetSecuritySelection */, false /* animate */);
Lucas Dupin93f714d2019-03-26 16:49:24 -0700369 assertThat(mBouncer.isScrimmed()).isFalse();
Lucas Dupinf9ca35e2018-05-16 20:41:35 -0700370 }
371
372 @Test
Lucas Dupin6f0d71f2018-03-23 17:26:06 -0700373 public void testWillDismissWithAction() {
374 mBouncer.ensureView();
375 Assert.assertFalse("Action not set yet", mBouncer.willDismissWithAction());
376 when(mKeyguardHostView.hasDismissActions()).thenReturn(true);
377 Assert.assertTrue("Action should exist", mBouncer.willDismissWithAction());
378 }
Lucas Dupin787f9a02019-04-24 14:56:52 -0700379
380 @Test
381 public void testShow_delaysIfFaceAuthIsRunning() {
Lucas Dupin4c507042019-07-22 16:47:34 -0700382 when(mUnlockMethodCache.isFaceAuthEnabled()).thenReturn(true);
Lucas Dupin787f9a02019-04-24 14:56:52 -0700383 mBouncer.show(true /* reset */);
384
385 ArgumentCaptor<Runnable> showRunnable = ArgumentCaptor.forClass(Runnable.class);
386 verify(mHandler).postDelayed(showRunnable.capture(),
387 eq(KeyguardBouncer.BOUNCER_FACE_DELAY));
388
389 mBouncer.hide(false /* destroyView */);
390 verify(mHandler).removeCallbacks(eq(showRunnable.getValue()));
391 }
392
393 @Test
394 public void testRegisterUpdateMonitorCallback() {
395 verify(mKeyguardUpdateMonitor).registerCallback(any());
396 }
Lucas Dupin6865b712017-09-11 12:28:03 -0700397}