blob: 67b8e07f2bec16af1781d910869be3baee8cd4fd [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;
Lucas Dupin055ef942019-08-15 11:41:52 -070024import static org.mockito.ArgumentMatchers.anyLong;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070025import static org.mockito.ArgumentMatchers.eq;
Lucas Dupin93f714d2019-03-26 16:49:24 -070026import static org.mockito.Mockito.doAnswer;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070027import static org.mockito.Mockito.never;
28import static org.mockito.Mockito.reset;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070029import static org.mockito.Mockito.verify;
30import static org.mockito.Mockito.verifyNoMoreInteractions;
31import static org.mockito.Mockito.verifyZeroInteractions;
32import static org.mockito.Mockito.when;
33
Jason Monka716bac2018-12-05 15:48:21 -050034import android.content.res.ColorStateList;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070035import android.graphics.Color;
Lucas Dupin787f9a02019-04-24 14:56:52 -070036import android.os.Handler;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070037import android.testing.AndroidTestingRunner;
38import android.testing.TestableLooper;
Lucas Dupin6865b712017-09-11 12:28:03 -070039import android.view.ViewGroup;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070040import android.view.ViewTreeObserver;
Lucas Dupin6865b712017-09-11 12:28:03 -070041import android.widget.FrameLayout;
42
Brett Chabot84151d92019-02-27 15:37:59 -080043import androidx.test.filters.SmallTest;
44
Lucas Dupin6865b712017-09-11 12:28:03 -070045import com.android.internal.widget.LockPatternUtils;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070046import com.android.keyguard.KeyguardHostView;
47import com.android.keyguard.KeyguardSecurityModel;
Lucas Dupin787f9a02019-04-24 14:56:52 -070048import com.android.keyguard.KeyguardUpdateMonitor;
Lucas Dupin6865b712017-09-11 12:28:03 -070049import com.android.keyguard.ViewMediatorCallback;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070050import com.android.systemui.DejankUtils;
Lucas Dupin6865b712017-09-11 12:28:03 -070051import com.android.systemui.SysuiTestCase;
52import com.android.systemui.keyguard.DismissCallbackRegistry;
Jason Monk297c04e2018-08-23 17:16:59 -040053import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
Dave Mankoff468d4f62019-05-08 14:56:29 -040054import com.android.systemui.plugins.FalsingManager;
Lucas Dupinc8f16e82019-09-17 18:24:50 -040055import com.android.systemui.statusbar.policy.KeyguardStateController;
Lucas Dupin6865b712017-09-11 12:28:03 -070056
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070057import org.junit.Assert;
58import org.junit.Before;
Lucas Dupin6865b712017-09-11 12:28:03 -070059import org.junit.Test;
60import org.junit.runner.RunWith;
Lucas Dupin787f9a02019-04-24 14:56:52 -070061import org.mockito.ArgumentCaptor;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070062import org.mockito.Mock;
63import org.mockito.MockitoAnnotations;
Lucas Dupin6865b712017-09-11 12:28:03 -070064
65@SmallTest
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070066@RunWith(AndroidTestingRunner.class)
Jason Monka716bac2018-12-05 15:48:21 -050067@TestableLooper.RunWithLooper
Lucas Dupin6865b712017-09-11 12:28:03 -070068public class KeyguardBouncerTest extends SysuiTestCase {
69
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070070 @Mock
71 private FalsingManager mFalsingManager;
72 @Mock
73 private ViewMediatorCallback mViewMediatorCallback;
74 @Mock
75 private LockPatternUtils mLockPatternUtils;
76 @Mock
77 private DismissCallbackRegistry mDismissCallbackRegistry;
78 @Mock
79 private KeyguardHostView mKeyguardHostView;
80 @Mock
81 private ViewTreeObserver mViewTreeObserver;
Lucas Dupin15a6b6c2018-04-16 14:50:20 +080082 @Mock
83 private KeyguardBouncer.BouncerExpansionCallback mExpansionCallback;
Lucas Dupin787f9a02019-04-24 14:56:52 -070084 @Mock
85 private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
86 @Mock
Lucas Dupinc8f16e82019-09-17 18:24:50 -040087 private KeyguardStateController mKeyguardStateController;
Lucas Dupin7825b942019-06-03 20:22:39 -070088 @Mock
Lucas Dupin055ef942019-08-15 11:41:52 -070089 private KeyguardBypassController mKeyguardBypassController;
90 @Mock
Lucas Dupin787f9a02019-04-24 14:56:52 -070091 private Handler mHandler;
Dave Mankofff44b13a2019-10-03 17:29:58 -040092 @Mock
93 private KeyguardSecurityModel mKeyguardSecurityModel;
Lucas Dupin6865b712017-09-11 12:28:03 -070094
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070095 private KeyguardBouncer mBouncer;
96
97 @Before
98 public void setup() {
Jason Monka716bac2018-12-05 15:48:21 -050099 com.android.systemui.util.Assert.sMainLooper = TestableLooper.get(this).getLooper();
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700100 MockitoAnnotations.initMocks(this);
Dave Mankoffe2294692019-08-14 11:53:13 -0400101 mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor);
Dave Mankofff44b13a2019-10-03 17:29:58 -0400102 mDependency.injectTestDependency(KeyguardSecurityModel.class, mKeyguardSecurityModel);
Lucas Dupind236ee32019-10-08 15:33:59 -0700103 mDependency.injectMockDependency(KeyguardStateController.class);
Dave Mankofff44b13a2019-10-03 17:29:58 -0400104 when(mKeyguardSecurityModel.getSecurityMode(anyInt()))
105 .thenReturn(KeyguardSecurityModel.SecurityMode.None);
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700106 DejankUtils.setImmediate(true);
107 final ViewGroup container = new FrameLayout(getContext());
108 when(mKeyguardHostView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
109 when(mKeyguardHostView.getHeight()).thenReturn(500);
110 mBouncer = new KeyguardBouncer(getContext(), mViewMediatorCallback,
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800111 mLockPatternUtils, container, mDismissCallbackRegistry, mFalsingManager,
Lucas Dupinc8f16e82019-09-17 18:24:50 -0400112 mExpansionCallback, mKeyguardStateController, mKeyguardUpdateMonitor,
Lucas Dupin055ef942019-08-15 11:41:52 -0700113 mKeyguardBypassController, mHandler) {
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700114 @Override
115 protected void inflateView() {
116 super.inflateView();
117 mKeyguardView = mKeyguardHostView;
118 }
119 };
Lucas Dupin6865b712017-09-11 12:28:03 -0700120 }
121
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700122 @Test
123 public void testInflateView_doesntCrash() {
124 mBouncer.inflateView();
125 }
126
127 @Test
128 public void testShow_notifiesFalsingManager() {
129 mBouncer.show(true);
130 verify(mFalsingManager).onBouncerShown();
131
132 mBouncer.show(true, false);
133 verifyNoMoreInteractions(mFalsingManager);
134 }
135
136 /**
137 * Regression test: Invisible bouncer when occluded.
138 */
139 @Test
140 public void testShow_bouncerIsVisible() {
141 // Expand notification panel as if we were in the keyguard.
142 mBouncer.ensureView();
143 mBouncer.setExpansion(1);
144
145 reset(mKeyguardHostView);
146 when(mKeyguardHostView.getHeight()).thenReturn(500);
147
148 mBouncer.show(true);
149 verify(mKeyguardHostView).setAlpha(eq(1f));
150 verify(mKeyguardHostView).setTranslationY(eq(0f));
151 }
152
153 @Test
154 public void testShow_notifiesVisibility() {
155 mBouncer.show(true);
156 verify(mViewMediatorCallback).onBouncerVisiblityChanged(eq(true));
Lucas Dupin2e838ac2019-04-17 16:50:58 -0700157 verify(mExpansionCallback).onStartingToShow();
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700158
159 // Not called again when visible
160 reset(mViewMediatorCallback);
161 mBouncer.show(true);
162 verifyNoMoreInteractions(mViewMediatorCallback);
163 }
164
165 @Test
166 public void testShow_triesToDismissKeyguard() {
167 mBouncer.show(true);
168 verify(mKeyguardHostView).dismiss(anyInt());
169 }
170
171 @Test
172 public void testShow_resetsSecuritySelection() {
173 mBouncer.show(false);
Lucas Dupin05726cd2018-03-13 14:00:24 -0700174 verify(mKeyguardHostView, never()).showPrimarySecurityScreen();
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700175
176 mBouncer.hide(false);
177 mBouncer.show(true);
178 verify(mKeyguardHostView).showPrimarySecurityScreen();
179 }
180
181 @Test
182 public void testShow_animatesKeyguardView() {
183 mBouncer.show(true);
184 verify(mKeyguardHostView).startAppearAnimation();
185 }
186
187 @Test
188 public void testShow_showsErrorMessage() {
189 final String errorMessage = "an error message";
190 when(mViewMediatorCallback.consumeCustomMessage()).thenReturn(errorMessage);
191 mBouncer.show(true);
192 verify(mKeyguardHostView).showErrorMessage(eq(errorMessage));
193 }
194
195 @Test
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800196 public void testSetExpansion_notifiesFalsingManager() {
Lucas Dupind2ce46d2018-04-04 17:00:29 -0700197 mBouncer.ensureView();
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800198 mBouncer.setExpansion(0.5f);
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700199
Lucas Dupin84993542018-10-11 19:23:45 -0700200 mBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700201 verify(mFalsingManager).onBouncerHidden();
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800202 verify(mExpansionCallback).onFullyHidden();
203
Lucas Dupin84993542018-10-11 19:23:45 -0700204 mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800205 verify(mFalsingManager).onBouncerShown();
206 verify(mExpansionCallback).onFullyShown();
Lucas Dupin84993542018-10-11 19:23:45 -0700207
208 verify(mExpansionCallback, never()).onStartingToHide();
209 mBouncer.setExpansion(0.9f);
210 verify(mExpansionCallback).onStartingToHide();
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800211 }
212
213 @Test
214 public void testSetExpansion_notifiesKeyguardView() {
215 mBouncer.ensureView();
216 mBouncer.setExpansion(0.1f);
217
218 mBouncer.setExpansion(0);
219 verify(mKeyguardHostView).onResume();
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700220 }
221
222 @Test
223 public void testHide_notifiesFalsingManager() {
224 mBouncer.hide(false);
225 verify(mFalsingManager).onBouncerHidden();
226 }
227
228 @Test
229 public void testHide_notifiesVisibility() {
230 mBouncer.hide(false);
231 verify(mViewMediatorCallback).onBouncerVisiblityChanged(eq(false));
232 }
233
234 @Test
235 public void testHide_notifiesDismissCallbackIfVisible() {
236 mBouncer.hide(false);
237 verifyZeroInteractions(mDismissCallbackRegistry);
238 mBouncer.show(false);
239 mBouncer.hide(false);
240 verify(mDismissCallbackRegistry).notifyDismissCancelled();
241 }
242
243 @Test
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800244 public void testHide_notShowingAnymore() {
245 mBouncer.ensureView();
246 mBouncer.show(false /* resetSecuritySelection */);
247 mBouncer.hide(false /* destroyViews */);
248 Assert.assertFalse("Not showing", mBouncer.isShowing());
249 }
250
251 @Test
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700252 public void testShowPromptReason_propagates() {
253 mBouncer.ensureView();
254 mBouncer.showPromptReason(1);
255 verify(mKeyguardHostView).showPromptReason(eq(1));
256 }
257
258 @Test
259 public void testShowMessage_propagates() {
260 final String message = "a message";
261 mBouncer.ensureView();
Jason Chang1e4a4bd2018-05-22 17:30:19 +0800262 mBouncer.showMessage(message, ColorStateList.valueOf(Color.GREEN));
263 verify(mKeyguardHostView).showMessage(eq(message), eq(ColorStateList.valueOf(Color.GREEN)));
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700264 }
265
266 @Test
267 public void testShowOnDismissAction_showsBouncer() {
Jason Monk297c04e2018-08-23 17:16:59 -0400268 final OnDismissAction dismissAction = () -> false;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700269 final Runnable cancelAction = () -> {};
270 mBouncer.showWithDismissAction(dismissAction, cancelAction);
271 verify(mKeyguardHostView).setOnDismissAction(dismissAction, cancelAction);
272 Assert.assertTrue("Should be showing", mBouncer.isShowing());
273 }
274
275 @Test
276 public void testStartPreHideAnimation_notifiesView() {
277 final boolean[] ran = {false};
278 final Runnable r = () -> ran[0] = true;
279 mBouncer.startPreHideAnimation(r);
280 Assert.assertTrue("Callback should have been invoked", ran[0]);
281
282 ran[0] = false;
283 mBouncer.ensureView();
284 mBouncer.startPreHideAnimation(r);
285 verify(mKeyguardHostView).startDisappearAnimation(r);
286 Assert.assertFalse("Callback should have been deferred", ran[0]);
287 }
288
289 @Test
Lucas Dupin3d565fa2018-03-20 15:40:14 -0700290 public void testIsShowing_animated() {
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700291 Assert.assertFalse("Show wasn't invoked yet", mBouncer.isShowing());
Lucas Dupin3d565fa2018-03-20 15:40:14 -0700292 mBouncer.show(true /* reset */);
293 Assert.assertTrue("Should be showing", mBouncer.isShowing());
294 }
295
296 @Test
297 public void testIsShowing_forSwipeUp() {
298 mBouncer.setExpansion(1f);
299 mBouncer.show(true /* reset */, false /* animated */);
300 Assert.assertFalse("Should only be showing after collapsing notification panel",
301 mBouncer.isShowing());
302 mBouncer.setExpansion(0f);
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700303 Assert.assertTrue("Should be showing", mBouncer.isShowing());
304 }
305
306 @Test
307 public void testSetExpansion() {
308 mBouncer.ensureView();
309 mBouncer.setExpansion(0.5f);
310 verify(mKeyguardHostView).setAlpha(anyFloat());
311 verify(mKeyguardHostView).setTranslationY(anyFloat());
312 }
313
314 @Test
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700315 public void testIsFullscreenBouncer_asksKeyguardView() {
316 mBouncer.ensureView();
317 mBouncer.isFullscreenBouncer();
318 verify(mKeyguardHostView).getCurrentSecurityMode();
319 verify(mKeyguardHostView, never()).getSecurityMode();
320 }
321
322 @Test
Lucas Dupin28dc9d72018-03-21 15:59:15 -0700323 public void testIsHiding_preHideOrHide() {
324 Assert.assertFalse("Should not be hiding on initial state", mBouncer.isAnimatingAway());
325 mBouncer.startPreHideAnimation(null /* runnable */);
326 Assert.assertTrue("Should be hiding during pre-hide", mBouncer.isAnimatingAway());
327 mBouncer.hide(false /* destroyView */);
328 Assert.assertFalse("Should be hidden after hide()", mBouncer.isAnimatingAway());
329 }
330
331 @Test
332 public void testIsHiding_skipsTranslation() {
333 mBouncer.show(false /* reset */);
334 reset(mKeyguardHostView);
335 mBouncer.startPreHideAnimation(null /* runnable */);
336 mBouncer.setExpansion(0.5f);
337 verify(mKeyguardHostView, never()).setTranslationY(anyFloat());
338 verify(mKeyguardHostView, never()).setAlpha(anyFloat());
339 }
340
341 @Test
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700342 public void testIsSecure() {
343 Assert.assertTrue("Bouncer is secure before inflating views", mBouncer.isSecure());
344
345 mBouncer.ensureView();
346 for (KeyguardSecurityModel.SecurityMode mode : KeyguardSecurityModel.SecurityMode.values()){
347 reset(mKeyguardHostView);
348 when(mKeyguardHostView.getSecurityMode()).thenReturn(mode);
349 Assert.assertEquals("Security doesn't match for mode: " + mode,
350 mBouncer.isSecure(), mode != KeyguardSecurityModel.SecurityMode.None);
351 }
352 }
Lucas Dupin6f0d71f2018-03-23 17:26:06 -0700353
354 @Test
Lucas Dupin93f714d2019-03-26 16:49:24 -0700355 public void testIsShowingScrimmed_true() {
356 doAnswer(invocation -> {
357 assertThat(mBouncer.isScrimmed()).isTrue();
358 return null;
359 }).when(mExpansionCallback).onFullyShown();
Lucas Dupinf9ca35e2018-05-16 20:41:35 -0700360 mBouncer.show(false /* resetSecuritySelection */, true /* animate */);
Lucas Dupin93f714d2019-03-26 16:49:24 -0700361 assertThat(mBouncer.isScrimmed()).isTrue();
362 mBouncer.hide(false /* destroyView */);
363 assertThat(mBouncer.isScrimmed()).isFalse();
364 }
365
366 @Test
367 public void testIsShowingScrimmed_false() {
368 doAnswer(invocation -> {
369 assertThat(mBouncer.isScrimmed()).isFalse();
370 return null;
371 }).when(mExpansionCallback).onFullyShown();
Lucas Dupinf9ca35e2018-05-16 20:41:35 -0700372 mBouncer.show(false /* resetSecuritySelection */, false /* animate */);
Lucas Dupin93f714d2019-03-26 16:49:24 -0700373 assertThat(mBouncer.isScrimmed()).isFalse();
Lucas Dupinf9ca35e2018-05-16 20:41:35 -0700374 }
375
376 @Test
Lucas Dupin6f0d71f2018-03-23 17:26:06 -0700377 public void testWillDismissWithAction() {
378 mBouncer.ensureView();
379 Assert.assertFalse("Action not set yet", mBouncer.willDismissWithAction());
380 when(mKeyguardHostView.hasDismissActions()).thenReturn(true);
381 Assert.assertTrue("Action should exist", mBouncer.willDismissWithAction());
382 }
Lucas Dupin787f9a02019-04-24 14:56:52 -0700383
384 @Test
385 public void testShow_delaysIfFaceAuthIsRunning() {
Lucas Dupinc8f16e82019-09-17 18:24:50 -0400386 when(mKeyguardStateController.isFaceAuthEnabled()).thenReturn(true);
Lucas Dupin787f9a02019-04-24 14:56:52 -0700387 mBouncer.show(true /* reset */);
388
389 ArgumentCaptor<Runnable> showRunnable = ArgumentCaptor.forClass(Runnable.class);
390 verify(mHandler).postDelayed(showRunnable.capture(),
391 eq(KeyguardBouncer.BOUNCER_FACE_DELAY));
392
393 mBouncer.hide(false /* destroyView */);
394 verify(mHandler).removeCallbacks(eq(showRunnable.getValue()));
395 }
396
397 @Test
Lucas Dupin055ef942019-08-15 11:41:52 -0700398 public void testShow_delaysIfFaceAuthIsRunning_unlessBypass() {
Lucas Dupinc8f16e82019-09-17 18:24:50 -0400399 when(mKeyguardStateController.isFaceAuthEnabled()).thenReturn(true);
Lucas Dupin055ef942019-08-15 11:41:52 -0700400 when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
401 mBouncer.show(true /* reset */);
402
403 verify(mHandler, never()).postDelayed(any(), anyLong());
404 }
405
406 @Test
Lucas Dupin787f9a02019-04-24 14:56:52 -0700407 public void testRegisterUpdateMonitorCallback() {
408 verify(mKeyguardUpdateMonitor).registerCallback(any());
409 }
Lucas Dupin273832d2019-07-23 13:44:12 -0700410
411 @Test
412 public void testInTransit_whenTranslation() {
413 mBouncer.show(true);
414 mBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
415 assertThat(mBouncer.inTransit()).isFalse();
416 mBouncer.setExpansion(0.5f);
417 assertThat(mBouncer.inTransit()).isTrue();
418 mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
419 assertThat(mBouncer.inTransit()).isFalse();
420 }
Lucas Dupin6865b712017-09-11 12:28:03 -0700421}