blob: e052ae2653f0e13eb3c1bfd81bf6b668ae58aaf4 [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 Dupinec239b92020-03-26 16:02:00 -070029import static org.mockito.Mockito.spy;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070030import static org.mockito.Mockito.verify;
31import static org.mockito.Mockito.verifyNoMoreInteractions;
32import static org.mockito.Mockito.verifyZeroInteractions;
33import static org.mockito.Mockito.when;
34
Jason Monka716bac2018-12-05 15:48:21 -050035import android.content.res.ColorStateList;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070036import android.graphics.Color;
Lucas Dupin787f9a02019-04-24 14:56:52 -070037import android.os.Handler;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070038import android.testing.AndroidTestingRunner;
39import android.testing.TestableLooper;
Lucas Dupin6865b712017-09-11 12:28:03 -070040import android.view.ViewGroup;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070041import android.view.ViewTreeObserver;
Lucas Dupin6865b712017-09-11 12:28:03 -070042import android.widget.FrameLayout;
43
Brett Chabot84151d92019-02-27 15:37:59 -080044import androidx.test.filters.SmallTest;
45
Lucas Dupin6865b712017-09-11 12:28:03 -070046import com.android.internal.widget.LockPatternUtils;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070047import com.android.keyguard.KeyguardHostView;
48import com.android.keyguard.KeyguardSecurityModel;
Lucas Dupin787f9a02019-04-24 14:56:52 -070049import com.android.keyguard.KeyguardUpdateMonitor;
Lucas Dupin6865b712017-09-11 12:28:03 -070050import com.android.keyguard.ViewMediatorCallback;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070051import com.android.systemui.DejankUtils;
Lucas Dupin6865b712017-09-11 12:28:03 -070052import com.android.systemui.SysuiTestCase;
53import com.android.systemui.keyguard.DismissCallbackRegistry;
Jason Monk297c04e2018-08-23 17:16:59 -040054import com.android.systemui.plugins.ActivityStarter.OnDismissAction;
Dave Mankoff468d4f62019-05-08 14:56:29 -040055import com.android.systemui.plugins.FalsingManager;
Lucas Dupinc8f16e82019-09-17 18:24:50 -040056import com.android.systemui.statusbar.policy.KeyguardStateController;
Lucas Dupin6865b712017-09-11 12:28:03 -070057
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070058import org.junit.Assert;
59import org.junit.Before;
Lucas Dupinec239b92020-03-26 16:02:00 -070060import org.junit.Rule;
Lucas Dupin6865b712017-09-11 12:28:03 -070061import org.junit.Test;
62import org.junit.runner.RunWith;
Lucas Dupin787f9a02019-04-24 14:56:52 -070063import org.mockito.ArgumentCaptor;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070064import org.mockito.Mock;
Lucas Dupinec239b92020-03-26 16:02:00 -070065import org.mockito.junit.MockitoJUnit;
66import org.mockito.junit.MockitoRule;
Lucas Dupin6865b712017-09-11 12:28:03 -070067
68@SmallTest
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070069@RunWith(AndroidTestingRunner.class)
Jason Monka716bac2018-12-05 15:48:21 -050070@TestableLooper.RunWithLooper
Lucas Dupin6865b712017-09-11 12:28:03 -070071public class KeyguardBouncerTest extends SysuiTestCase {
72
Lucas Dupin0df9b7a2018-03-15 17:53:17 -070073 @Mock
74 private FalsingManager mFalsingManager;
75 @Mock
76 private ViewMediatorCallback mViewMediatorCallback;
77 @Mock
78 private LockPatternUtils mLockPatternUtils;
79 @Mock
80 private DismissCallbackRegistry mDismissCallbackRegistry;
81 @Mock
82 private KeyguardHostView mKeyguardHostView;
83 @Mock
84 private ViewTreeObserver mViewTreeObserver;
Lucas Dupin15a6b6c2018-04-16 14:50:20 +080085 @Mock
86 private KeyguardBouncer.BouncerExpansionCallback mExpansionCallback;
Lucas Dupin787f9a02019-04-24 14:56:52 -070087 @Mock
88 private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
89 @Mock
Lucas Dupinc8f16e82019-09-17 18:24:50 -040090 private KeyguardStateController mKeyguardStateController;
Lucas Dupin7825b942019-06-03 20:22:39 -070091 @Mock
Lucas Dupin055ef942019-08-15 11:41:52 -070092 private KeyguardBypassController mKeyguardBypassController;
93 @Mock
Lucas Dupin787f9a02019-04-24 14:56:52 -070094 private Handler mHandler;
Dave Mankofff44b13a2019-10-03 17:29:58 -040095 @Mock
96 private KeyguardSecurityModel mKeyguardSecurityModel;
Lucas Dupinec239b92020-03-26 16:02:00 -070097 @Rule
98 public MockitoRule mRule = MockitoJUnit.rule();
99 private ViewGroup mRootView;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700100 private KeyguardBouncer mBouncer;
101
102 @Before
103 public void setup() {
Beverly1467c9e2020-02-18 13:31:29 -0500104 allowTestableLooperAsMainThread();
Dave Mankoffe2294692019-08-14 11:53:13 -0400105 mDependency.injectTestDependency(KeyguardUpdateMonitor.class, mKeyguardUpdateMonitor);
Dave Mankofff44b13a2019-10-03 17:29:58 -0400106 mDependency.injectTestDependency(KeyguardSecurityModel.class, mKeyguardSecurityModel);
Lucas Dupind236ee32019-10-08 15:33:59 -0700107 mDependency.injectMockDependency(KeyguardStateController.class);
Dave Mankofff44b13a2019-10-03 17:29:58 -0400108 when(mKeyguardSecurityModel.getSecurityMode(anyInt()))
109 .thenReturn(KeyguardSecurityModel.SecurityMode.None);
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700110 DejankUtils.setImmediate(true);
111 final ViewGroup container = new FrameLayout(getContext());
112 when(mKeyguardHostView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
113 when(mKeyguardHostView.getHeight()).thenReturn(500);
114 mBouncer = new KeyguardBouncer(getContext(), mViewMediatorCallback,
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800115 mLockPatternUtils, container, mDismissCallbackRegistry, mFalsingManager,
Lucas Dupinc8f16e82019-09-17 18:24:50 -0400116 mExpansionCallback, mKeyguardStateController, mKeyguardUpdateMonitor,
Lucas Dupin055ef942019-08-15 11:41:52 -0700117 mKeyguardBypassController, mHandler) {
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700118 @Override
119 protected void inflateView() {
120 super.inflateView();
121 mKeyguardView = mKeyguardHostView;
Lucas Dupinec239b92020-03-26 16:02:00 -0700122 mRoot = spy(mRoot);
123 mRootView = mRoot;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700124 }
125 };
Lucas Dupin6865b712017-09-11 12:28:03 -0700126 }
127
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700128 @Test
129 public void testInflateView_doesntCrash() {
130 mBouncer.inflateView();
131 }
132
133 @Test
134 public void testShow_notifiesFalsingManager() {
135 mBouncer.show(true);
136 verify(mFalsingManager).onBouncerShown();
137
138 mBouncer.show(true, false);
139 verifyNoMoreInteractions(mFalsingManager);
140 }
141
142 /**
143 * Regression test: Invisible bouncer when occluded.
144 */
145 @Test
146 public void testShow_bouncerIsVisible() {
147 // Expand notification panel as if we were in the keyguard.
148 mBouncer.ensureView();
149 mBouncer.setExpansion(1);
150
151 reset(mKeyguardHostView);
152 when(mKeyguardHostView.getHeight()).thenReturn(500);
153
154 mBouncer.show(true);
155 verify(mKeyguardHostView).setAlpha(eq(1f));
156 verify(mKeyguardHostView).setTranslationY(eq(0f));
157 }
158
159 @Test
160 public void testShow_notifiesVisibility() {
161 mBouncer.show(true);
162 verify(mViewMediatorCallback).onBouncerVisiblityChanged(eq(true));
Lucas Dupin2e838ac2019-04-17 16:50:58 -0700163 verify(mExpansionCallback).onStartingToShow();
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700164
165 // Not called again when visible
166 reset(mViewMediatorCallback);
167 mBouncer.show(true);
168 verifyNoMoreInteractions(mViewMediatorCallback);
169 }
170
171 @Test
172 public void testShow_triesToDismissKeyguard() {
173 mBouncer.show(true);
174 verify(mKeyguardHostView).dismiss(anyInt());
175 }
176
177 @Test
178 public void testShow_resetsSecuritySelection() {
179 mBouncer.show(false);
Lucas Dupin05726cd2018-03-13 14:00:24 -0700180 verify(mKeyguardHostView, never()).showPrimarySecurityScreen();
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700181
182 mBouncer.hide(false);
183 mBouncer.show(true);
184 verify(mKeyguardHostView).showPrimarySecurityScreen();
185 }
186
187 @Test
188 public void testShow_animatesKeyguardView() {
189 mBouncer.show(true);
190 verify(mKeyguardHostView).startAppearAnimation();
191 }
192
193 @Test
194 public void testShow_showsErrorMessage() {
195 final String errorMessage = "an error message";
196 when(mViewMediatorCallback.consumeCustomMessage()).thenReturn(errorMessage);
197 mBouncer.show(true);
198 verify(mKeyguardHostView).showErrorMessage(eq(errorMessage));
199 }
200
201 @Test
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800202 public void testSetExpansion_notifiesFalsingManager() {
Lucas Dupind2ce46d2018-04-04 17:00:29 -0700203 mBouncer.ensureView();
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800204 mBouncer.setExpansion(0.5f);
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700205
Lucas Dupin84993542018-10-11 19:23:45 -0700206 mBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700207 verify(mFalsingManager).onBouncerHidden();
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800208 verify(mExpansionCallback).onFullyHidden();
209
Lucas Dupin84993542018-10-11 19:23:45 -0700210 mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800211 verify(mFalsingManager).onBouncerShown();
212 verify(mExpansionCallback).onFullyShown();
Lucas Dupin84993542018-10-11 19:23:45 -0700213
214 verify(mExpansionCallback, never()).onStartingToHide();
215 mBouncer.setExpansion(0.9f);
216 verify(mExpansionCallback).onStartingToHide();
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800217 }
218
219 @Test
220 public void testSetExpansion_notifiesKeyguardView() {
221 mBouncer.ensureView();
222 mBouncer.setExpansion(0.1f);
223
224 mBouncer.setExpansion(0);
225 verify(mKeyguardHostView).onResume();
Lucas Dupinec239b92020-03-26 16:02:00 -0700226 verify(mRootView).announceForAccessibility(any());
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700227 }
228
229 @Test
230 public void testHide_notifiesFalsingManager() {
231 mBouncer.hide(false);
232 verify(mFalsingManager).onBouncerHidden();
233 }
234
235 @Test
236 public void testHide_notifiesVisibility() {
237 mBouncer.hide(false);
238 verify(mViewMediatorCallback).onBouncerVisiblityChanged(eq(false));
239 }
240
241 @Test
242 public void testHide_notifiesDismissCallbackIfVisible() {
243 mBouncer.hide(false);
244 verifyZeroInteractions(mDismissCallbackRegistry);
245 mBouncer.show(false);
246 mBouncer.hide(false);
247 verify(mDismissCallbackRegistry).notifyDismissCancelled();
248 }
249
250 @Test
Lucas Dupin15a6b6c2018-04-16 14:50:20 +0800251 public void testHide_notShowingAnymore() {
252 mBouncer.ensureView();
253 mBouncer.show(false /* resetSecuritySelection */);
254 mBouncer.hide(false /* destroyViews */);
255 Assert.assertFalse("Not showing", mBouncer.isShowing());
256 }
257
258 @Test
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700259 public void testShowPromptReason_propagates() {
260 mBouncer.ensureView();
261 mBouncer.showPromptReason(1);
262 verify(mKeyguardHostView).showPromptReason(eq(1));
263 }
264
265 @Test
266 public void testShowMessage_propagates() {
267 final String message = "a message";
268 mBouncer.ensureView();
Jason Chang1e4a4bd2018-05-22 17:30:19 +0800269 mBouncer.showMessage(message, ColorStateList.valueOf(Color.GREEN));
270 verify(mKeyguardHostView).showMessage(eq(message), eq(ColorStateList.valueOf(Color.GREEN)));
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700271 }
272
273 @Test
274 public void testShowOnDismissAction_showsBouncer() {
Jason Monk297c04e2018-08-23 17:16:59 -0400275 final OnDismissAction dismissAction = () -> false;
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700276 final Runnable cancelAction = () -> {};
277 mBouncer.showWithDismissAction(dismissAction, cancelAction);
278 verify(mKeyguardHostView).setOnDismissAction(dismissAction, cancelAction);
279 Assert.assertTrue("Should be showing", mBouncer.isShowing());
280 }
281
282 @Test
283 public void testStartPreHideAnimation_notifiesView() {
284 final boolean[] ran = {false};
285 final Runnable r = () -> ran[0] = true;
286 mBouncer.startPreHideAnimation(r);
287 Assert.assertTrue("Callback should have been invoked", ran[0]);
288
289 ran[0] = false;
290 mBouncer.ensureView();
291 mBouncer.startPreHideAnimation(r);
292 verify(mKeyguardHostView).startDisappearAnimation(r);
293 Assert.assertFalse("Callback should have been deferred", ran[0]);
294 }
295
296 @Test
Lucas Dupin3d565fa2018-03-20 15:40:14 -0700297 public void testIsShowing_animated() {
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700298 Assert.assertFalse("Show wasn't invoked yet", mBouncer.isShowing());
Lucas Dupin3d565fa2018-03-20 15:40:14 -0700299 mBouncer.show(true /* reset */);
300 Assert.assertTrue("Should be showing", mBouncer.isShowing());
301 }
302
303 @Test
304 public void testIsShowing_forSwipeUp() {
305 mBouncer.setExpansion(1f);
306 mBouncer.show(true /* reset */, false /* animated */);
307 Assert.assertFalse("Should only be showing after collapsing notification panel",
308 mBouncer.isShowing());
309 mBouncer.setExpansion(0f);
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700310 Assert.assertTrue("Should be showing", mBouncer.isShowing());
311 }
312
313 @Test
314 public void testSetExpansion() {
315 mBouncer.ensureView();
316 mBouncer.setExpansion(0.5f);
317 verify(mKeyguardHostView).setAlpha(anyFloat());
318 verify(mKeyguardHostView).setTranslationY(anyFloat());
319 }
320
321 @Test
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700322 public void testIsFullscreenBouncer_asksKeyguardView() {
323 mBouncer.ensureView();
324 mBouncer.isFullscreenBouncer();
325 verify(mKeyguardHostView).getCurrentSecurityMode();
326 verify(mKeyguardHostView, never()).getSecurityMode();
327 }
328
329 @Test
Lucas Dupin28dc9d72018-03-21 15:59:15 -0700330 public void testIsHiding_preHideOrHide() {
331 Assert.assertFalse("Should not be hiding on initial state", mBouncer.isAnimatingAway());
332 mBouncer.startPreHideAnimation(null /* runnable */);
333 Assert.assertTrue("Should be hiding during pre-hide", mBouncer.isAnimatingAway());
334 mBouncer.hide(false /* destroyView */);
335 Assert.assertFalse("Should be hidden after hide()", mBouncer.isAnimatingAway());
336 }
337
338 @Test
339 public void testIsHiding_skipsTranslation() {
340 mBouncer.show(false /* reset */);
341 reset(mKeyguardHostView);
342 mBouncer.startPreHideAnimation(null /* runnable */);
343 mBouncer.setExpansion(0.5f);
344 verify(mKeyguardHostView, never()).setTranslationY(anyFloat());
345 verify(mKeyguardHostView, never()).setAlpha(anyFloat());
346 }
347
348 @Test
Lucas Dupin0df9b7a2018-03-15 17:53:17 -0700349 public void testIsSecure() {
350 Assert.assertTrue("Bouncer is secure before inflating views", mBouncer.isSecure());
351
352 mBouncer.ensureView();
353 for (KeyguardSecurityModel.SecurityMode mode : KeyguardSecurityModel.SecurityMode.values()){
354 reset(mKeyguardHostView);
355 when(mKeyguardHostView.getSecurityMode()).thenReturn(mode);
356 Assert.assertEquals("Security doesn't match for mode: " + mode,
357 mBouncer.isSecure(), mode != KeyguardSecurityModel.SecurityMode.None);
358 }
359 }
Lucas Dupin6f0d71f2018-03-23 17:26:06 -0700360
361 @Test
Lucas Dupin93f714d2019-03-26 16:49:24 -0700362 public void testIsShowingScrimmed_true() {
363 doAnswer(invocation -> {
364 assertThat(mBouncer.isScrimmed()).isTrue();
365 return null;
366 }).when(mExpansionCallback).onFullyShown();
Lucas Dupinf9ca35e2018-05-16 20:41:35 -0700367 mBouncer.show(false /* resetSecuritySelection */, true /* animate */);
Lucas Dupin93f714d2019-03-26 16:49:24 -0700368 assertThat(mBouncer.isScrimmed()).isTrue();
369 mBouncer.hide(false /* destroyView */);
370 assertThat(mBouncer.isScrimmed()).isFalse();
371 }
372
373 @Test
374 public void testIsShowingScrimmed_false() {
375 doAnswer(invocation -> {
376 assertThat(mBouncer.isScrimmed()).isFalse();
377 return null;
378 }).when(mExpansionCallback).onFullyShown();
Lucas Dupinf9ca35e2018-05-16 20:41:35 -0700379 mBouncer.show(false /* resetSecuritySelection */, false /* animate */);
Lucas Dupin93f714d2019-03-26 16:49:24 -0700380 assertThat(mBouncer.isScrimmed()).isFalse();
Lucas Dupinf9ca35e2018-05-16 20:41:35 -0700381 }
382
383 @Test
Lucas Dupin6f0d71f2018-03-23 17:26:06 -0700384 public void testWillDismissWithAction() {
385 mBouncer.ensureView();
386 Assert.assertFalse("Action not set yet", mBouncer.willDismissWithAction());
387 when(mKeyguardHostView.hasDismissActions()).thenReturn(true);
388 Assert.assertTrue("Action should exist", mBouncer.willDismissWithAction());
389 }
Lucas Dupin787f9a02019-04-24 14:56:52 -0700390
391 @Test
392 public void testShow_delaysIfFaceAuthIsRunning() {
Lucas Dupinc8f16e82019-09-17 18:24:50 -0400393 when(mKeyguardStateController.isFaceAuthEnabled()).thenReturn(true);
Lucas Dupin787f9a02019-04-24 14:56:52 -0700394 mBouncer.show(true /* reset */);
395
396 ArgumentCaptor<Runnable> showRunnable = ArgumentCaptor.forClass(Runnable.class);
397 verify(mHandler).postDelayed(showRunnable.capture(),
398 eq(KeyguardBouncer.BOUNCER_FACE_DELAY));
399
400 mBouncer.hide(false /* destroyView */);
401 verify(mHandler).removeCallbacks(eq(showRunnable.getValue()));
402 }
403
404 @Test
Lucas Dupin055ef942019-08-15 11:41:52 -0700405 public void testShow_delaysIfFaceAuthIsRunning_unlessBypass() {
Lucas Dupinc8f16e82019-09-17 18:24:50 -0400406 when(mKeyguardStateController.isFaceAuthEnabled()).thenReturn(true);
Lucas Dupin055ef942019-08-15 11:41:52 -0700407 when(mKeyguardBypassController.getBypassEnabled()).thenReturn(true);
408 mBouncer.show(true /* reset */);
409
410 verify(mHandler, never()).postDelayed(any(), anyLong());
411 }
412
413 @Test
Lucas Dupin787f9a02019-04-24 14:56:52 -0700414 public void testRegisterUpdateMonitorCallback() {
415 verify(mKeyguardUpdateMonitor).registerCallback(any());
416 }
Lucas Dupin273832d2019-07-23 13:44:12 -0700417
418 @Test
419 public void testInTransit_whenTranslation() {
420 mBouncer.show(true);
421 mBouncer.setExpansion(KeyguardBouncer.EXPANSION_HIDDEN);
422 assertThat(mBouncer.inTransit()).isFalse();
423 mBouncer.setExpansion(0.5f);
424 assertThat(mBouncer.inTransit()).isTrue();
425 mBouncer.setExpansion(KeyguardBouncer.EXPANSION_VISIBLE);
426 assertThat(mBouncer.inTransit()).isFalse();
427 }
Lucas Dupin6865b712017-09-11 12:28:03 -0700428}