blob: 27c00c0821bdc41f0b4ee1d27a0882227b8c27a1 [file] [log] [blame]
Lucas Dupin9e3fa102017-11-08 17:16:55 -08001/*
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 Dupin82aa1632017-12-13 00:13:57 -080019import static com.android.systemui.statusbar.phone.ScrimController.VISIBILITY_FULLY_OPAQUE;
20import static com.android.systemui.statusbar.phone.ScrimController.VISIBILITY_FULLY_TRANSPARENT;
21import static com.android.systemui.statusbar.phone.ScrimController.VISIBILITY_SEMI_TRANSPARENT;
22
23import static org.mockito.ArgumentMatchers.any;
24import static org.mockito.ArgumentMatchers.anyInt;
25import static org.mockito.ArgumentMatchers.anyLong;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080026import static org.mockito.Mockito.mock;
27import static org.mockito.Mockito.never;
Lucas Dupin82aa1632017-12-13 00:13:57 -080028import static org.mockito.Mockito.reset;
Lucas Dupin067136c2018-03-27 18:03:25 -070029import static org.mockito.Mockito.spy;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080030import static org.mockito.Mockito.verify;
Lucas Dupineea53b32017-12-18 13:47:14 -080031import static org.mockito.Mockito.verifyZeroInteractions;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080032import static org.mockito.Mockito.when;
33
34import android.animation.Animator;
Lucas Dupin80a3fcc2018-02-07 10:49:55 -080035import android.animation.ValueAnimator;
Lucas Dupin82aa1632017-12-13 00:13:57 -080036import android.app.AlarmManager;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080037import android.graphics.Color;
38import android.os.Handler;
39import android.os.Looper;
40import android.support.test.filters.SmallTest;
41import android.testing.AndroidTestingRunner;
42import android.testing.TestableLooper;
43import android.view.View;
44
Lucas Dupin7517b5d2017-08-22 12:51:25 -070045import com.android.keyguard.KeyguardUpdateMonitor;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080046import com.android.systemui.SysuiTestCase;
47import com.android.systemui.statusbar.ScrimView;
48import com.android.systemui.util.wakelock.WakeLock;
49import com.android.systemui.utils.os.FakeHandler;
50
51import org.junit.Assert;
52import org.junit.Before;
53import org.junit.Test;
54import org.junit.runner.RunWith;
55
Lucas Dupin78949b82018-04-03 18:54:39 -070056import java.util.Arrays;
57import java.util.HashSet;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080058import java.util.function.Consumer;
59
60@RunWith(AndroidTestingRunner.class)
61@TestableLooper.RunWithLooper
62@SmallTest
63public class ScrimControllerTest extends SysuiTestCase {
64
65 private SynchronousScrimController mScrimController;
66 private ScrimView mScrimBehind;
67 private ScrimView mScrimInFront;
Lucas Dupin82aa1632017-12-13 00:13:57 -080068 private Consumer<Integer> mScrimVisibilityCallback;
69 private int mScrimVisibility;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080070 private LightBarController mLightBarController;
71 private DozeParameters mDozeParamenters;
72 private WakeLock mWakeLock;
73 private boolean mAlwaysOnEnabled;
Lucas Dupin82aa1632017-12-13 00:13:57 -080074 private AlarmManager mAlarmManager;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080075
76 @Before
77 public void setup() {
78 mLightBarController = mock(LightBarController.class);
Lucas Dupin067136c2018-03-27 18:03:25 -070079 mScrimBehind = spy(new ScrimView(getContext()));
Lucas Dupin9e3fa102017-11-08 17:16:55 -080080 mScrimInFront = new ScrimView(getContext());
Lucas Dupin9e3fa102017-11-08 17:16:55 -080081 mWakeLock = mock(WakeLock.class);
Lucas Dupin82aa1632017-12-13 00:13:57 -080082 mAlarmManager = mock(AlarmManager.class);
Lucas Dupin9e3fa102017-11-08 17:16:55 -080083 mAlwaysOnEnabled = true;
Lucas Dupin82aa1632017-12-13 00:13:57 -080084 mScrimVisibilityCallback = (Integer visible) -> mScrimVisibility = visible;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080085 mDozeParamenters = mock(DozeParameters.class);
86 when(mDozeParamenters.getAlwaysOn()).thenAnswer(invocation -> mAlwaysOnEnabled);
Lucas Dupin43d0d732017-11-16 11:23:49 -080087 when(mDozeParamenters.getDisplayNeedsBlanking()).thenReturn(true);
Lucas Dupin9e3fa102017-11-08 17:16:55 -080088 mScrimController = new SynchronousScrimController(mLightBarController, mScrimBehind,
Selim Cinek99e9adf2018-03-15 09:17:47 -070089 mScrimInFront, mScrimVisibilityCallback, mDozeParamenters,
Lucas Dupin82aa1632017-12-13 00:13:57 -080090 mAlarmManager);
Lucas Dupin9e3fa102017-11-08 17:16:55 -080091 }
92
93 @Test
94 public void initialState() {
95 Assert.assertEquals("ScrimController should start initialized",
96 mScrimController.getState(), ScrimState.UNINITIALIZED);
97 }
98
99 @Test
100 public void transitionToKeyguard() {
101 mScrimController.transitionTo(ScrimState.KEYGUARD);
102 mScrimController.finishAnimationsImmediately();
103 // Front scrim should be transparent
104 // Back scrim should be visible without tint
Lucas Dupin82aa1632017-12-13 00:13:57 -0800105 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800106 assertScrimTint(mScrimBehind, false /* tinted */);
107 }
108
109 @Test
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700110 public void transitionToAod_withRegularWallpaper() {
111 mScrimController.transitionTo(ScrimState.AOD);
112 mScrimController.finishAnimationsImmediately();
113 // Front scrim should be transparent
114 // Back scrim should be visible with tint
Lucas Dupin82aa1632017-12-13 00:13:57 -0800115 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700116 assertScrimTint(mScrimBehind, true /* tinted */);
117 assertScrimTint(mScrimInFront, true /* tinted */);
118 }
119
120 @Test
121 public void transitionToAod_withAodWallpaper() {
122 mScrimController.setWallpaperSupportsAmbientMode(true);
123 mScrimController.transitionTo(ScrimState.AOD);
124 mScrimController.finishAnimationsImmediately();
125 // Front scrim should be transparent
126 // Back scrim should be transparent
Lucas Dupin82aa1632017-12-13 00:13:57 -0800127 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
128
129 // Move on to PULSING and check if the back scrim is still transparent
130 mScrimController.transitionTo(ScrimState.PULSING);
131 mScrimController.finishAnimationsImmediately();
132 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700133 }
134
135 @Test
136 public void transitionToAod_withAodWallpaperAndLockScreenWallpaper() {
137 ScrimState.AOD.mKeyguardUpdateMonitor = new KeyguardUpdateMonitor(getContext()) {
138 @Override
139 public boolean hasLockscreenWallpaper() {
140 return true;
141 }
142 };
143 mScrimController.setWallpaperSupportsAmbientMode(true);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800144 mScrimController.transitionTo(ScrimState.AOD);
145 mScrimController.finishAnimationsImmediately();
146 // Front scrim should be transparent
147 // Back scrim should be visible with tint
Lucas Dupin82aa1632017-12-13 00:13:57 -0800148 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800149 assertScrimTint(mScrimBehind, true /* tinted */);
150 assertScrimTint(mScrimInFront, true /* tinted */);
151 }
152
153 @Test
154 public void transitionToPulsing() {
Lucas Dupin82aa1632017-12-13 00:13:57 -0800155 // Pre-condition
156 // Need to go to AoD first because PULSING doesn't change
157 // the back scrim opacity - otherwise it would hide AoD wallpapers.
158 mScrimController.setWallpaperSupportsAmbientMode(false);
159 mScrimController.transitionTo(ScrimState.AOD);
160 mScrimController.finishAnimationsImmediately();
161 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
162
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800163 mScrimController.transitionTo(ScrimState.PULSING);
164 mScrimController.finishAnimationsImmediately();
165 // Front scrim should be transparent
166 // Back scrim should be visible with tint
167 // Pulse callback should have been invoked
Lucas Dupin82aa1632017-12-13 00:13:57 -0800168 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800169 assertScrimTint(mScrimBehind, true /* tinted */);
170 }
171
172 @Test
Lucas Dupinbc9aac12018-03-04 20:18:15 -0800173 public void transitionToKeyguardBouncer() {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800174 mScrimController.transitionTo(ScrimState.BOUNCER);
175 mScrimController.finishAnimationsImmediately();
176 // Front scrim should be transparent
177 // Back scrim should be visible without tint
Lucas Dupinbc9aac12018-03-04 20:18:15 -0800178 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
179 assertScrimTint(mScrimBehind, false /* tinted */);
180 }
181
182 @Test
183 public void transitionToBouncer() {
Lucas Dupin05726cd2018-03-13 14:00:24 -0700184 mScrimController.transitionTo(ScrimState.BOUNCER_SCRIMMED);
Lucas Dupinbc9aac12018-03-04 20:18:15 -0800185 mScrimController.finishAnimationsImmediately();
186 // Front scrim should be transparent
187 // Back scrim should be visible without tint
188 assertScrimVisibility(VISIBILITY_SEMI_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800189 assertScrimTint(mScrimBehind, false /* tinted */);
190 }
191
192 @Test
193 public void transitionToUnlocked() {
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800194 mScrimController.setPanelExpansion(0f);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800195 mScrimController.transitionTo(ScrimState.UNLOCKED);
196 mScrimController.finishAnimationsImmediately();
197 // Front scrim should be transparent
198 // Back scrim should be transparent
Lucas Dupin82aa1632017-12-13 00:13:57 -0800199 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800200 assertScrimTint(mScrimBehind, false /* tinted */);
201 assertScrimTint(mScrimInFront, false /* tinted */);
202
203 // Back scrim should be visible after start dragging
204 mScrimController.setPanelExpansion(0.5f);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800205 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800206 }
207
208 @Test
Lucas Dupin67f02632018-03-12 11:08:31 -0700209 public void panelExpansionAffectsAlpha() {
210 mScrimController.setPanelExpansion(0f);
211 mScrimController.setPanelExpansion(0.5f);
212 mScrimController.transitionTo(ScrimState.UNLOCKED);
213 mScrimController.finishAnimationsImmediately();
214
215 final float scrimAlpha = mScrimBehind.getViewAlpha();
Lucas Dupin067136c2018-03-27 18:03:25 -0700216 reset(mScrimBehind);
Lucas Dupin67f02632018-03-12 11:08:31 -0700217 mScrimController.setExpansionAffectsAlpha(false);
218 mScrimController.setPanelExpansion(0.8f);
Lucas Dupin067136c2018-03-27 18:03:25 -0700219 verifyZeroInteractions(mScrimBehind);
Lucas Dupin67f02632018-03-12 11:08:31 -0700220 Assert.assertEquals("Scrim opacity shouldn't change when setExpansionAffectsAlpha "
221 + "is false", scrimAlpha, mScrimBehind.getViewAlpha(), 0.01f);
222
223 mScrimController.setExpansionAffectsAlpha(true);
224 mScrimController.setPanelExpansion(0.1f);
225 Assert.assertNotEquals("Scrim opacity should change when setExpansionAffectsAlpha "
226 + "is true", scrimAlpha, mScrimBehind.getViewAlpha(), 0.01f);
227 }
228
229 @Test
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800230 public void transitionToUnlockedFromAod() {
231 // Simulate unlock with fingerprint
232 mScrimController.transitionTo(ScrimState.AOD);
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800233 mScrimController.setPanelExpansion(0f);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800234 mScrimController.finishAnimationsImmediately();
235 mScrimController.transitionTo(ScrimState.UNLOCKED);
236 // Immediately tinted after the transition starts
237 assertScrimTint(mScrimInFront, true /* tinted */);
238 assertScrimTint(mScrimBehind, true /* tinted */);
239 mScrimController.finishAnimationsImmediately();
240 // Front scrim should be transparent
241 // Back scrim should be transparent
242 // Neither scrims should be tinted anymore after the animation.
Lucas Dupin82aa1632017-12-13 00:13:57 -0800243 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800244 assertScrimTint(mScrimInFront, false /* tinted */);
245 assertScrimTint(mScrimBehind, false /* tinted */);
246 }
247
248 @Test
Lucas Dupinea0116e2018-04-05 10:09:29 -0700249 public void scrimBlanksBeforeLeavingAod() {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800250 // Simulate unlock with fingerprint
251 mScrimController.transitionTo(ScrimState.AOD);
252 mScrimController.finishAnimationsImmediately();
253 mScrimController.transitionTo(ScrimState.UNLOCKED,
254 new ScrimController.Callback() {
255 @Override
256 public void onDisplayBlanked() {
257 // Front scrim should be black in the middle of the transition
258 Assert.assertTrue("Scrim should be visible during transition. Alpha: "
259 + mScrimInFront.getViewAlpha(), mScrimInFront.getViewAlpha() > 0);
260 assertScrimTint(mScrimInFront, true /* tinted */);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800261 Assert.assertSame("Scrim should be visible during transition.",
262 mScrimVisibility, VISIBILITY_FULLY_OPAQUE);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800263 }
264 });
265 mScrimController.finishAnimationsImmediately();
266 }
267
268 @Test
269 public void testScrimCallback() {
270 int[] callOrder = {0, 0, 0};
271 int[] currentCall = {0};
272 mScrimController.transitionTo(ScrimState.AOD, new ScrimController.Callback() {
273 @Override
274 public void onStart() {
275 callOrder[0] = ++currentCall[0];
276 }
277
278 @Override
279 public void onDisplayBlanked() {
280 callOrder[1] = ++currentCall[0];
281 }
282
283 @Override
284 public void onFinished() {
285 callOrder[2] = ++currentCall[0];
286 }
287 });
288 mScrimController.finishAnimationsImmediately();
289 Assert.assertEquals("onStart called in wrong order", 1, callOrder[0]);
290 Assert.assertEquals("onDisplayBlanked called in wrong order", 2, callOrder[1]);
291 Assert.assertEquals("onFinished called in wrong order", 3, callOrder[2]);
292 }
293
294 @Test
295 public void testScrimCallbacksWithoutAmbientDisplay() {
296 mAlwaysOnEnabled = false;
297 testScrimCallback();
298 }
299
300 @Test
301 public void testScrimCallbackCancelled() {
302 boolean[] cancelledCalled = {false};
303 mScrimController.transitionTo(ScrimState.AOD, new ScrimController.Callback() {
304 @Override
305 public void onCancelled() {
306 cancelledCalled[0] = true;
307 }
308 });
309 mScrimController.transitionTo(ScrimState.PULSING);
310 Assert.assertTrue("onCancelled should have been called", cancelledCalled[0]);
311 }
312
313 @Test
Lucas Dupineea53b32017-12-18 13:47:14 -0800314 public void testHoldsWakeLock_whenAOD() {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800315 mScrimController.transitionTo(ScrimState.AOD);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800316 verify(mWakeLock).acquire();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800317 verify(mWakeLock, never()).release();
318 mScrimController.finishAnimationsImmediately();
Lucas Dupin82aa1632017-12-13 00:13:57 -0800319 verify(mWakeLock).release();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800320 }
321
Lucas Dupin19aba8e2017-12-11 12:42:26 -0800322 @Test
Lucas Dupineea53b32017-12-18 13:47:14 -0800323 public void testDoesNotHoldWakeLock_whenUnlocking() {
324 mScrimController.transitionTo(ScrimState.UNLOCKED);
325 mScrimController.finishAnimationsImmediately();
326 verifyZeroInteractions(mWakeLock);
327 }
328
329 @Test
Lucas Dupin19aba8e2017-12-11 12:42:26 -0800330 public void testCallbackInvokedOnSameStateTransition() {
331 mScrimController.transitionTo(ScrimState.UNLOCKED);
332 mScrimController.finishAnimationsImmediately();
333 ScrimController.Callback callback = mock(ScrimController.Callback.class);
334 mScrimController.transitionTo(ScrimState.UNLOCKED, callback);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800335 verify(callback).onFinished();
336 }
337
338 @Test
339 public void testHoldsAodWallpaperAnimationLock() {
340 // Pre-conditions
341 mScrimController.transitionTo(ScrimState.AOD);
342 mScrimController.finishAnimationsImmediately();
343 reset(mWakeLock);
344
345 mScrimController.onHideWallpaperTimeout();
346 verify(mWakeLock).acquire();
347 verify(mWakeLock, never()).release();
348 mScrimController.finishAnimationsImmediately();
349 verify(mWakeLock).release();
350 }
351
352 @Test
Lucas Dupin16cfe452018-02-08 13:14:50 -0800353 public void testWillHideAodWallpaper() {
Lucas Dupin82aa1632017-12-13 00:13:57 -0800354 mScrimController.setWallpaperSupportsAmbientMode(true);
355 mScrimController.transitionTo(ScrimState.AOD);
356 verify(mAlarmManager).setExact(anyInt(), anyLong(), any(), any(), any());
357 mScrimController.transitionTo(ScrimState.KEYGUARD);
358 verify(mAlarmManager).cancel(any(AlarmManager.OnAlarmListener.class));
Lucas Dupin19aba8e2017-12-11 12:42:26 -0800359 }
360
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800361 @Test
362 public void testConservesExpansionOpacityAfterTransition() {
363 mScrimController.transitionTo(ScrimState.UNLOCKED);
364 mScrimController.setPanelExpansion(0.5f);
365 mScrimController.finishAnimationsImmediately();
366
367 final float expandedAlpha = mScrimBehind.getViewAlpha();
368
369 mScrimController.transitionTo(ScrimState.BRIGHTNESS_MIRROR);
370 mScrimController.finishAnimationsImmediately();
371 mScrimController.transitionTo(ScrimState.UNLOCKED);
372 mScrimController.finishAnimationsImmediately();
373
374 Assert.assertEquals("Scrim expansion opacity wasn't conserved when transitioning back",
375 expandedAlpha, mScrimBehind.getViewAlpha(), 0.01f);
376 }
377
378 @Test
379 public void cancelsOldAnimationBeforeBlanking() {
380 mScrimController.transitionTo(ScrimState.AOD);
381 mScrimController.finishAnimationsImmediately();
382 // Consume whatever value we had before
383 mScrimController.wasAnimationJustCancelled();
384
385 mScrimController.transitionTo(ScrimState.KEYGUARD);
386 mScrimController.finishAnimationsImmediately();
387 Assert.assertTrue(mScrimController.wasAnimationJustCancelled());
388 }
389
Lucas Dupinb380c882018-02-25 21:57:17 -0800390 /**
391 * Number of visible notifications affects scrim opacity.
392 */
393 @Test
394 public void testNotificationDensity() {
395 mScrimController.transitionTo(ScrimState.KEYGUARD);
396 mScrimController.finishAnimationsImmediately();
397
398 mScrimController.setNotificationCount(0);
399 mScrimController.finishAnimationsImmediately();
400 Assert.assertEquals("lower density when no notifications",
401 ScrimController.GRADIENT_SCRIM_ALPHA, mScrimBehind.getViewAlpha(), 0.01f);
402
403 mScrimController.setNotificationCount(3);
404 mScrimController.finishAnimationsImmediately();
405 Assert.assertEquals("stronger density when notifications are visible",
406 ScrimController.GRADIENT_SCRIM_ALPHA_BUSY, mScrimBehind.getViewAlpha(), 0.01f);
407 }
408
409 /**
410 * Moving from/to states conserves old notification density.
411 */
412 @Test
413 public void testConservesNotificationDensity() {
414 testConservesNotificationDensity(0 /* count */, ScrimController.GRADIENT_SCRIM_ALPHA);
415 testConservesNotificationDensity(3 /* count */, ScrimController.GRADIENT_SCRIM_ALPHA_BUSY);
416 }
417
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800418 @Test
Lucas Dupin38962d72018-03-14 12:41:39 -0700419 public void testScrimFocus() {
420 mScrimController.transitionTo(ScrimState.AOD);
421 Assert.assertFalse("Should not be focusable on AOD", mScrimBehind.isFocusable());
422 Assert.assertFalse("Should not be focusable on AOD", mScrimInFront.isFocusable());
423
424 mScrimController.transitionTo(ScrimState.KEYGUARD);
425 Assert.assertTrue("Should be focusable on keyguard", mScrimBehind.isFocusable());
426 Assert.assertTrue("Should be focusable on keyguard", mScrimInFront.isFocusable());
427 }
428
Lucas Dupind5107302018-03-19 15:30:29 -0700429 @Test
430 public void testHidesShowWhenLockedActivity() {
431 mScrimController.setWallpaperSupportsAmbientMode(true);
432 mScrimController.setKeyguardOccluded(true);
433 mScrimController.transitionTo(ScrimState.AOD);
434 mScrimController.finishAnimationsImmediately();
435 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
436
437 mScrimController.transitionTo(ScrimState.PULSING);
438 mScrimController.finishAnimationsImmediately();
439 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
440 }
441
Lucas Dupin78949b82018-04-03 18:54:39 -0700442 @Test
443 public void testEatsTouchEvent() {
444 HashSet<ScrimState> eatsTouches =
445 new HashSet<>(Arrays.asList(ScrimState.AOD, ScrimState.PULSING));
446 for (ScrimState state : ScrimState.values()) {
447 if (state == ScrimState.UNINITIALIZED) {
448 continue;
449 }
450 mScrimController.transitionTo(state);
451 mScrimController.finishAnimationsImmediately();
452 Assert.assertEquals("Should be clickable unless AOD or PULSING, was: " + state,
453 mScrimBehind.getViewAlpha() != 0 && !eatsTouches.contains(state),
454 mScrimBehind.isClickable());
455 }
456 }
457
Lucas Dupinea0116e2018-04-05 10:09:29 -0700458 @Test
459 public void testAnimatesTransitionToAod() {
460 when(mDozeParamenters.shouldControlScreenOff()).thenReturn(false);
461 ScrimState.AOD.prepare(ScrimState.KEYGUARD);
462 Assert.assertFalse("No animation when ColorFade kicks in",
463 ScrimState.AOD.getAnimateChange());
464
465 reset(mDozeParamenters);
466 when(mDozeParamenters.shouldControlScreenOff()).thenReturn(true);
467 ScrimState.AOD.prepare(ScrimState.KEYGUARD);
468 Assert.assertTrue("Animate scrims when ColorFade won't be triggered",
469 ScrimState.AOD.getAnimateChange());
470 }
471
Lucas Dupinb380c882018-02-25 21:57:17 -0800472 /**
473 * Conserves old notification density after leaving state and coming back.
474 *
475 * @param count How many notification.
476 * @param expectedAlpha Expected alpha.
477 */
478 private void testConservesNotificationDensity(int count, float expectedAlpha) {
479 mScrimController.setNotificationCount(count);
480 mScrimController.transitionTo(ScrimState.UNLOCKED);
481 mScrimController.finishAnimationsImmediately();
482
483 mScrimController.transitionTo(ScrimState.KEYGUARD);
484 mScrimController.finishAnimationsImmediately();
485
486 Assert.assertEquals("Doesn't respect notification busyness after transition",
487 expectedAlpha, mScrimBehind.getViewAlpha(), 0.01f);
488 }
489
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800490 private void assertScrimTint(ScrimView scrimView, boolean tinted) {
491 final boolean viewIsTinted = scrimView.getTint() != Color.TRANSPARENT;
492 final String name = scrimView == mScrimInFront ? "front" : "back";
493 Assert.assertEquals("Tint test failed at state " + mScrimController.getState()
494 +" with scrim: " + name + " and tint: " + Integer.toHexString(scrimView.getTint()),
495 tinted, viewIsTinted);
496 }
497
Lucas Dupin82aa1632017-12-13 00:13:57 -0800498 private void assertScrimVisibility(int inFront, int behind) {
499 boolean inFrontVisible = inFront != ScrimController.VISIBILITY_FULLY_TRANSPARENT;
500 boolean behindVisible = behind != ScrimController.VISIBILITY_FULLY_TRANSPARENT;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800501 Assert.assertEquals("Unexpected front scrim visibility. Alpha is "
Lucas Dupin82aa1632017-12-13 00:13:57 -0800502 + mScrimInFront.getViewAlpha(), inFrontVisible, mScrimInFront.getViewAlpha() > 0);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800503 Assert.assertEquals("Unexpected back scrim visibility. Alpha is "
Lucas Dupin82aa1632017-12-13 00:13:57 -0800504 + mScrimBehind.getViewAlpha(), behindVisible, mScrimBehind.getViewAlpha() > 0);
505
506 final int visibility;
507 if (inFront == VISIBILITY_FULLY_OPAQUE || behind == VISIBILITY_FULLY_OPAQUE) {
508 visibility = VISIBILITY_FULLY_OPAQUE;
509 } else if (inFront > VISIBILITY_FULLY_TRANSPARENT || behind > VISIBILITY_FULLY_TRANSPARENT) {
510 visibility = VISIBILITY_SEMI_TRANSPARENT;
511 } else {
512 visibility = VISIBILITY_FULLY_TRANSPARENT;
513 }
514 Assert.assertEquals("Invalid visibility.", visibility, mScrimVisibility);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800515 }
516
517 /**
518 * Special version of ScrimController where animations have 0 duration for test purposes.
519 */
520 private class SynchronousScrimController extends ScrimController {
521
522 private FakeHandler mHandler;
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800523 private boolean mAnimationCancelled;
Lucas Dupin16cfe452018-02-08 13:14:50 -0800524 boolean mOnPreDrawCalled;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800525
Lucas Dupin3503c5f2018-03-02 19:04:00 -0800526 SynchronousScrimController(LightBarController lightBarController,
Selim Cinek99e9adf2018-03-15 09:17:47 -0700527 ScrimView scrimBehind, ScrimView scrimInFront,
Lucas Dupin82aa1632017-12-13 00:13:57 -0800528 Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters,
529 AlarmManager alarmManager) {
Selim Cinek99e9adf2018-03-15 09:17:47 -0700530 super(lightBarController, scrimBehind, scrimInFront,
Lucas Dupin82aa1632017-12-13 00:13:57 -0800531 scrimVisibleListener, dozeParameters, alarmManager);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800532 mHandler = new FakeHandler(Looper.myLooper());
533 }
534
Lucas Dupin16cfe452018-02-08 13:14:50 -0800535 @Override
536 public boolean onPreDraw() {
537 mOnPreDrawCalled = true;
538 return super.onPreDraw();
539 }
540
Lucas Dupin3503c5f2018-03-02 19:04:00 -0800541 void finishAnimationsImmediately() {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800542 boolean[] animationFinished = {false};
543 setOnAnimationFinished(()-> animationFinished[0] = true);
544
545 // Execute code that will trigger animations.
546 onPreDraw();
547
548 // Force finish screen blanking.
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800549 mHandler.dispatchQueuedMessages();
550 // Force finish all animations.
551 endAnimation(mScrimBehind, TAG_KEY_ANIM);
552 endAnimation(mScrimInFront, TAG_KEY_ANIM);
553
554 if (!animationFinished[0]) {
555 throw new IllegalStateException("Animation never finished");
556 }
557 }
558
Lucas Dupin3503c5f2018-03-02 19:04:00 -0800559 boolean wasAnimationJustCancelled() {
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800560 final boolean wasCancelled = mAnimationCancelled;
561 mAnimationCancelled = false;
562 return wasCancelled;
563 }
564
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800565 private void endAnimation(View scrimView, int tag) {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800566 Animator animator = (Animator) scrimView.getTag(tag);
567 if (animator != null) {
568 animator.end();
569 }
570 }
571
572 @Override
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800573 protected void cancelAnimator(ValueAnimator previousAnimator) {
574 super.cancelAnimator(previousAnimator);
575 mAnimationCancelled = true;
576 }
577
578 @Override
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800579 protected Handler getHandler() {
580 return mHandler;
581 }
582
583 @Override
584 protected WakeLock createWakeLock() {
585 return mWakeLock;
586 }
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800587
588 /**
589 * Do not wait for a frame since we're in a test environment.
590 * @param callback What to execute.
591 */
592 @Override
Lucas Dupin0791d972018-03-26 13:32:16 -0700593 protected void doOnTheNextFrame(Runnable callback) {
594 callback.run();
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800595 }
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800596 }
597
598}