blob: 7743c6b443a543bb11ffa47d0d466c13c0c3c8a1 [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 Dupin9e3fa102017-11-08 17:16:55 -080029import static org.mockito.Mockito.verify;
Lucas Dupineea53b32017-12-18 13:47:14 -080030import static org.mockito.Mockito.verifyZeroInteractions;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080031import static org.mockito.Mockito.when;
32
33import android.animation.Animator;
Lucas Dupin80a3fcc2018-02-07 10:49:55 -080034import android.animation.ValueAnimator;
Lucas Dupin82aa1632017-12-13 00:13:57 -080035import android.app.AlarmManager;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080036import android.graphics.Color;
37import android.os.Handler;
38import android.os.Looper;
39import android.support.test.filters.SmallTest;
40import android.testing.AndroidTestingRunner;
41import android.testing.TestableLooper;
42import android.view.View;
43
Lucas Dupin7517b5d2017-08-22 12:51:25 -070044import com.android.keyguard.KeyguardUpdateMonitor;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080045import com.android.systemui.SysuiTestCase;
46import com.android.systemui.statusbar.ScrimView;
47import com.android.systemui.util.wakelock.WakeLock;
48import com.android.systemui.utils.os.FakeHandler;
49
50import org.junit.Assert;
51import org.junit.Before;
52import org.junit.Test;
53import org.junit.runner.RunWith;
54
55import java.util.function.Consumer;
56
57@RunWith(AndroidTestingRunner.class)
58@TestableLooper.RunWithLooper
59@SmallTest
60public class ScrimControllerTest extends SysuiTestCase {
61
62 private SynchronousScrimController mScrimController;
63 private ScrimView mScrimBehind;
64 private ScrimView mScrimInFront;
Lucas Dupin82aa1632017-12-13 00:13:57 -080065 private Consumer<Integer> mScrimVisibilityCallback;
66 private int mScrimVisibility;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080067 private LightBarController mLightBarController;
68 private DozeParameters mDozeParamenters;
69 private WakeLock mWakeLock;
70 private boolean mAlwaysOnEnabled;
Lucas Dupin82aa1632017-12-13 00:13:57 -080071 private AlarmManager mAlarmManager;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080072
73 @Before
74 public void setup() {
75 mLightBarController = mock(LightBarController.class);
76 mScrimBehind = new ScrimView(getContext());
77 mScrimInFront = new ScrimView(getContext());
Lucas Dupin9e3fa102017-11-08 17:16:55 -080078 mWakeLock = mock(WakeLock.class);
Lucas Dupin82aa1632017-12-13 00:13:57 -080079 mAlarmManager = mock(AlarmManager.class);
Lucas Dupin9e3fa102017-11-08 17:16:55 -080080 mAlwaysOnEnabled = true;
Lucas Dupin82aa1632017-12-13 00:13:57 -080081 mScrimVisibilityCallback = (Integer visible) -> mScrimVisibility = visible;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080082 mDozeParamenters = mock(DozeParameters.class);
83 when(mDozeParamenters.getAlwaysOn()).thenAnswer(invocation -> mAlwaysOnEnabled);
Lucas Dupin43d0d732017-11-16 11:23:49 -080084 when(mDozeParamenters.getDisplayNeedsBlanking()).thenReturn(true);
Lucas Dupin9e3fa102017-11-08 17:16:55 -080085 mScrimController = new SynchronousScrimController(mLightBarController, mScrimBehind,
Selim Cinek99e9adf2018-03-15 09:17:47 -070086 mScrimInFront, mScrimVisibilityCallback, mDozeParamenters,
Lucas Dupin82aa1632017-12-13 00:13:57 -080087 mAlarmManager);
Lucas Dupin9e3fa102017-11-08 17:16:55 -080088 }
89
90 @Test
91 public void initialState() {
92 Assert.assertEquals("ScrimController should start initialized",
93 mScrimController.getState(), ScrimState.UNINITIALIZED);
94 }
95
96 @Test
97 public void transitionToKeyguard() {
98 mScrimController.transitionTo(ScrimState.KEYGUARD);
99 mScrimController.finishAnimationsImmediately();
100 // Front scrim should be transparent
101 // Back scrim should be visible without tint
Lucas Dupin82aa1632017-12-13 00:13:57 -0800102 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800103 assertScrimTint(mScrimBehind, false /* tinted */);
104 }
105
106 @Test
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700107 public void transitionToAod_withRegularWallpaper() {
108 mScrimController.transitionTo(ScrimState.AOD);
109 mScrimController.finishAnimationsImmediately();
110 // Front scrim should be transparent
111 // Back scrim should be visible with tint
Lucas Dupin82aa1632017-12-13 00:13:57 -0800112 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700113 assertScrimTint(mScrimBehind, true /* tinted */);
114 assertScrimTint(mScrimInFront, true /* tinted */);
115 }
116
117 @Test
118 public void transitionToAod_withAodWallpaper() {
119 mScrimController.setWallpaperSupportsAmbientMode(true);
120 mScrimController.transitionTo(ScrimState.AOD);
121 mScrimController.finishAnimationsImmediately();
122 // Front scrim should be transparent
123 // Back scrim should be transparent
Lucas Dupin82aa1632017-12-13 00:13:57 -0800124 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
125
126 // Move on to PULSING and check if the back scrim is still transparent
127 mScrimController.transitionTo(ScrimState.PULSING);
128 mScrimController.finishAnimationsImmediately();
129 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700130 }
131
132 @Test
133 public void transitionToAod_withAodWallpaperAndLockScreenWallpaper() {
134 ScrimState.AOD.mKeyguardUpdateMonitor = new KeyguardUpdateMonitor(getContext()) {
135 @Override
136 public boolean hasLockscreenWallpaper() {
137 return true;
138 }
139 };
140 mScrimController.setWallpaperSupportsAmbientMode(true);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800141 mScrimController.transitionTo(ScrimState.AOD);
142 mScrimController.finishAnimationsImmediately();
143 // Front scrim should be transparent
144 // Back scrim should be visible with tint
Lucas Dupin82aa1632017-12-13 00:13:57 -0800145 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800146 assertScrimTint(mScrimBehind, true /* tinted */);
147 assertScrimTint(mScrimInFront, true /* tinted */);
148 }
149
150 @Test
151 public void transitionToPulsing() {
Lucas Dupin82aa1632017-12-13 00:13:57 -0800152 // Pre-condition
153 // Need to go to AoD first because PULSING doesn't change
154 // the back scrim opacity - otherwise it would hide AoD wallpapers.
155 mScrimController.setWallpaperSupportsAmbientMode(false);
156 mScrimController.transitionTo(ScrimState.AOD);
157 mScrimController.finishAnimationsImmediately();
158 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
159
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800160 mScrimController.transitionTo(ScrimState.PULSING);
161 mScrimController.finishAnimationsImmediately();
162 // Front scrim should be transparent
163 // Back scrim should be visible with tint
164 // Pulse callback should have been invoked
Lucas Dupin82aa1632017-12-13 00:13:57 -0800165 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800166 assertScrimTint(mScrimBehind, true /* tinted */);
167 }
168
169 @Test
Lucas Dupinbc9aac12018-03-04 20:18:15 -0800170 public void transitionToKeyguardBouncer() {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800171 mScrimController.transitionTo(ScrimState.BOUNCER);
172 mScrimController.finishAnimationsImmediately();
173 // Front scrim should be transparent
174 // Back scrim should be visible without tint
Lucas Dupinbc9aac12018-03-04 20:18:15 -0800175 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
176 assertScrimTint(mScrimBehind, false /* tinted */);
177 }
178
179 @Test
180 public void transitionToBouncer() {
Lucas Dupin05726cd2018-03-13 14:00:24 -0700181 mScrimController.transitionTo(ScrimState.BOUNCER_SCRIMMED);
Lucas Dupinbc9aac12018-03-04 20:18:15 -0800182 mScrimController.finishAnimationsImmediately();
183 // Front scrim should be transparent
184 // Back scrim should be visible without tint
185 assertScrimVisibility(VISIBILITY_SEMI_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800186 assertScrimTint(mScrimBehind, false /* tinted */);
187 }
188
189 @Test
190 public void transitionToUnlocked() {
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800191 mScrimController.setPanelExpansion(0f);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800192 mScrimController.transitionTo(ScrimState.UNLOCKED);
193 mScrimController.finishAnimationsImmediately();
194 // Front scrim should be transparent
195 // Back scrim should be transparent
Lucas Dupin82aa1632017-12-13 00:13:57 -0800196 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800197 assertScrimTint(mScrimBehind, false /* tinted */);
198 assertScrimTint(mScrimInFront, false /* tinted */);
199
200 // Back scrim should be visible after start dragging
201 mScrimController.setPanelExpansion(0.5f);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800202 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800203 }
204
205 @Test
Lucas Dupin67f02632018-03-12 11:08:31 -0700206 public void panelExpansionAffectsAlpha() {
207 mScrimController.setPanelExpansion(0f);
208 mScrimController.setPanelExpansion(0.5f);
209 mScrimController.transitionTo(ScrimState.UNLOCKED);
210 mScrimController.finishAnimationsImmediately();
211
212 final float scrimAlpha = mScrimBehind.getViewAlpha();
213 mScrimController.setExpansionAffectsAlpha(false);
214 mScrimController.setPanelExpansion(0.8f);
215 Assert.assertEquals("Scrim opacity shouldn't change when setExpansionAffectsAlpha "
216 + "is false", scrimAlpha, mScrimBehind.getViewAlpha(), 0.01f);
217
218 mScrimController.setExpansionAffectsAlpha(true);
219 mScrimController.setPanelExpansion(0.1f);
220 Assert.assertNotEquals("Scrim opacity should change when setExpansionAffectsAlpha "
221 + "is true", scrimAlpha, mScrimBehind.getViewAlpha(), 0.01f);
222 }
223
224 @Test
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800225 public void transitionToUnlockedFromAod() {
226 // Simulate unlock with fingerprint
227 mScrimController.transitionTo(ScrimState.AOD);
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800228 mScrimController.setPanelExpansion(0f);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800229 mScrimController.finishAnimationsImmediately();
230 mScrimController.transitionTo(ScrimState.UNLOCKED);
231 // Immediately tinted after the transition starts
232 assertScrimTint(mScrimInFront, true /* tinted */);
233 assertScrimTint(mScrimBehind, true /* tinted */);
234 mScrimController.finishAnimationsImmediately();
235 // Front scrim should be transparent
236 // Back scrim should be transparent
237 // Neither scrims should be tinted anymore after the animation.
Lucas Dupin82aa1632017-12-13 00:13:57 -0800238 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800239 assertScrimTint(mScrimInFront, false /* tinted */);
240 assertScrimTint(mScrimBehind, false /* tinted */);
241 }
242
243 @Test
244 public void scrimBlanksBeforeLeavingAoD() {
245 // Simulate unlock with fingerprint
246 mScrimController.transitionTo(ScrimState.AOD);
247 mScrimController.finishAnimationsImmediately();
248 mScrimController.transitionTo(ScrimState.UNLOCKED,
249 new ScrimController.Callback() {
250 @Override
251 public void onDisplayBlanked() {
252 // Front scrim should be black in the middle of the transition
253 Assert.assertTrue("Scrim should be visible during transition. Alpha: "
254 + mScrimInFront.getViewAlpha(), mScrimInFront.getViewAlpha() > 0);
255 assertScrimTint(mScrimInFront, true /* tinted */);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800256 Assert.assertSame("Scrim should be visible during transition.",
257 mScrimVisibility, VISIBILITY_FULLY_OPAQUE);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800258 }
259 });
260 mScrimController.finishAnimationsImmediately();
261 }
262
263 @Test
264 public void testScrimCallback() {
265 int[] callOrder = {0, 0, 0};
266 int[] currentCall = {0};
267 mScrimController.transitionTo(ScrimState.AOD, new ScrimController.Callback() {
268 @Override
269 public void onStart() {
270 callOrder[0] = ++currentCall[0];
271 }
272
273 @Override
274 public void onDisplayBlanked() {
275 callOrder[1] = ++currentCall[0];
276 }
277
278 @Override
279 public void onFinished() {
280 callOrder[2] = ++currentCall[0];
281 }
282 });
283 mScrimController.finishAnimationsImmediately();
284 Assert.assertEquals("onStart called in wrong order", 1, callOrder[0]);
285 Assert.assertEquals("onDisplayBlanked called in wrong order", 2, callOrder[1]);
286 Assert.assertEquals("onFinished called in wrong order", 3, callOrder[2]);
287 }
288
289 @Test
290 public void testScrimCallbacksWithoutAmbientDisplay() {
291 mAlwaysOnEnabled = false;
292 testScrimCallback();
293 }
294
295 @Test
296 public void testScrimCallbackCancelled() {
297 boolean[] cancelledCalled = {false};
298 mScrimController.transitionTo(ScrimState.AOD, new ScrimController.Callback() {
299 @Override
300 public void onCancelled() {
301 cancelledCalled[0] = true;
302 }
303 });
304 mScrimController.transitionTo(ScrimState.PULSING);
305 Assert.assertTrue("onCancelled should have been called", cancelledCalled[0]);
306 }
307
308 @Test
Lucas Dupineea53b32017-12-18 13:47:14 -0800309 public void testHoldsWakeLock_whenAOD() {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800310 mScrimController.transitionTo(ScrimState.AOD);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800311 verify(mWakeLock).acquire();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800312 verify(mWakeLock, never()).release();
313 mScrimController.finishAnimationsImmediately();
Lucas Dupin82aa1632017-12-13 00:13:57 -0800314 verify(mWakeLock).release();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800315 }
316
Lucas Dupin19aba8e2017-12-11 12:42:26 -0800317 @Test
Lucas Dupineea53b32017-12-18 13:47:14 -0800318 public void testDoesNotHoldWakeLock_whenUnlocking() {
319 mScrimController.transitionTo(ScrimState.UNLOCKED);
320 mScrimController.finishAnimationsImmediately();
321 verifyZeroInteractions(mWakeLock);
322 }
323
324 @Test
Lucas Dupin19aba8e2017-12-11 12:42:26 -0800325 public void testCallbackInvokedOnSameStateTransition() {
326 mScrimController.transitionTo(ScrimState.UNLOCKED);
327 mScrimController.finishAnimationsImmediately();
328 ScrimController.Callback callback = mock(ScrimController.Callback.class);
329 mScrimController.transitionTo(ScrimState.UNLOCKED, callback);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800330 verify(callback).onFinished();
331 }
332
333 @Test
334 public void testHoldsAodWallpaperAnimationLock() {
335 // Pre-conditions
336 mScrimController.transitionTo(ScrimState.AOD);
337 mScrimController.finishAnimationsImmediately();
338 reset(mWakeLock);
339
340 mScrimController.onHideWallpaperTimeout();
341 verify(mWakeLock).acquire();
342 verify(mWakeLock, never()).release();
343 mScrimController.finishAnimationsImmediately();
344 verify(mWakeLock).release();
345 }
346
347 @Test
Lucas Dupin16cfe452018-02-08 13:14:50 -0800348 public void testWillHideAodWallpaper() {
Lucas Dupin82aa1632017-12-13 00:13:57 -0800349 mScrimController.setWallpaperSupportsAmbientMode(true);
350 mScrimController.transitionTo(ScrimState.AOD);
351 verify(mAlarmManager).setExact(anyInt(), anyLong(), any(), any(), any());
352 mScrimController.transitionTo(ScrimState.KEYGUARD);
353 verify(mAlarmManager).cancel(any(AlarmManager.OnAlarmListener.class));
Lucas Dupin19aba8e2017-12-11 12:42:26 -0800354 }
355
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800356 @Test
357 public void testConservesExpansionOpacityAfterTransition() {
358 mScrimController.transitionTo(ScrimState.UNLOCKED);
359 mScrimController.setPanelExpansion(0.5f);
360 mScrimController.finishAnimationsImmediately();
361
362 final float expandedAlpha = mScrimBehind.getViewAlpha();
363
364 mScrimController.transitionTo(ScrimState.BRIGHTNESS_MIRROR);
365 mScrimController.finishAnimationsImmediately();
366 mScrimController.transitionTo(ScrimState.UNLOCKED);
367 mScrimController.finishAnimationsImmediately();
368
369 Assert.assertEquals("Scrim expansion opacity wasn't conserved when transitioning back",
370 expandedAlpha, mScrimBehind.getViewAlpha(), 0.01f);
371 }
372
373 @Test
374 public void cancelsOldAnimationBeforeBlanking() {
375 mScrimController.transitionTo(ScrimState.AOD);
376 mScrimController.finishAnimationsImmediately();
377 // Consume whatever value we had before
378 mScrimController.wasAnimationJustCancelled();
379
380 mScrimController.transitionTo(ScrimState.KEYGUARD);
381 mScrimController.finishAnimationsImmediately();
382 Assert.assertTrue(mScrimController.wasAnimationJustCancelled());
383 }
384
Lucas Dupinb380c882018-02-25 21:57:17 -0800385 /**
386 * Number of visible notifications affects scrim opacity.
387 */
388 @Test
389 public void testNotificationDensity() {
390 mScrimController.transitionTo(ScrimState.KEYGUARD);
391 mScrimController.finishAnimationsImmediately();
392
393 mScrimController.setNotificationCount(0);
394 mScrimController.finishAnimationsImmediately();
395 Assert.assertEquals("lower density when no notifications",
396 ScrimController.GRADIENT_SCRIM_ALPHA, mScrimBehind.getViewAlpha(), 0.01f);
397
398 mScrimController.setNotificationCount(3);
399 mScrimController.finishAnimationsImmediately();
400 Assert.assertEquals("stronger density when notifications are visible",
401 ScrimController.GRADIENT_SCRIM_ALPHA_BUSY, mScrimBehind.getViewAlpha(), 0.01f);
402 }
403
404 /**
405 * Moving from/to states conserves old notification density.
406 */
407 @Test
408 public void testConservesNotificationDensity() {
409 testConservesNotificationDensity(0 /* count */, ScrimController.GRADIENT_SCRIM_ALPHA);
410 testConservesNotificationDensity(3 /* count */, ScrimController.GRADIENT_SCRIM_ALPHA_BUSY);
411 }
412
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800413 @Test
Lucas Dupin38962d72018-03-14 12:41:39 -0700414 public void testScrimFocus() {
415 mScrimController.transitionTo(ScrimState.AOD);
416 Assert.assertFalse("Should not be focusable on AOD", mScrimBehind.isFocusable());
417 Assert.assertFalse("Should not be focusable on AOD", mScrimInFront.isFocusable());
418
419 mScrimController.transitionTo(ScrimState.KEYGUARD);
420 Assert.assertTrue("Should be focusable on keyguard", mScrimBehind.isFocusable());
421 Assert.assertTrue("Should be focusable on keyguard", mScrimInFront.isFocusable());
422 }
423
Lucas Dupind5107302018-03-19 15:30:29 -0700424 @Test
425 public void testHidesShowWhenLockedActivity() {
426 mScrimController.setWallpaperSupportsAmbientMode(true);
427 mScrimController.setKeyguardOccluded(true);
428 mScrimController.transitionTo(ScrimState.AOD);
429 mScrimController.finishAnimationsImmediately();
430 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
431
432 mScrimController.transitionTo(ScrimState.PULSING);
433 mScrimController.finishAnimationsImmediately();
434 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_OPAQUE);
435 }
436
Lucas Dupinb380c882018-02-25 21:57:17 -0800437 /**
438 * Conserves old notification density after leaving state and coming back.
439 *
440 * @param count How many notification.
441 * @param expectedAlpha Expected alpha.
442 */
443 private void testConservesNotificationDensity(int count, float expectedAlpha) {
444 mScrimController.setNotificationCount(count);
445 mScrimController.transitionTo(ScrimState.UNLOCKED);
446 mScrimController.finishAnimationsImmediately();
447
448 mScrimController.transitionTo(ScrimState.KEYGUARD);
449 mScrimController.finishAnimationsImmediately();
450
451 Assert.assertEquals("Doesn't respect notification busyness after transition",
452 expectedAlpha, mScrimBehind.getViewAlpha(), 0.01f);
453 }
454
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800455 private void assertScrimTint(ScrimView scrimView, boolean tinted) {
456 final boolean viewIsTinted = scrimView.getTint() != Color.TRANSPARENT;
457 final String name = scrimView == mScrimInFront ? "front" : "back";
458 Assert.assertEquals("Tint test failed at state " + mScrimController.getState()
459 +" with scrim: " + name + " and tint: " + Integer.toHexString(scrimView.getTint()),
460 tinted, viewIsTinted);
461 }
462
Lucas Dupin82aa1632017-12-13 00:13:57 -0800463 private void assertScrimVisibility(int inFront, int behind) {
464 boolean inFrontVisible = inFront != ScrimController.VISIBILITY_FULLY_TRANSPARENT;
465 boolean behindVisible = behind != ScrimController.VISIBILITY_FULLY_TRANSPARENT;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800466 Assert.assertEquals("Unexpected front scrim visibility. Alpha is "
Lucas Dupin82aa1632017-12-13 00:13:57 -0800467 + mScrimInFront.getViewAlpha(), inFrontVisible, mScrimInFront.getViewAlpha() > 0);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800468 Assert.assertEquals("Unexpected back scrim visibility. Alpha is "
Lucas Dupin82aa1632017-12-13 00:13:57 -0800469 + mScrimBehind.getViewAlpha(), behindVisible, mScrimBehind.getViewAlpha() > 0);
470
471 final int visibility;
472 if (inFront == VISIBILITY_FULLY_OPAQUE || behind == VISIBILITY_FULLY_OPAQUE) {
473 visibility = VISIBILITY_FULLY_OPAQUE;
474 } else if (inFront > VISIBILITY_FULLY_TRANSPARENT || behind > VISIBILITY_FULLY_TRANSPARENT) {
475 visibility = VISIBILITY_SEMI_TRANSPARENT;
476 } else {
477 visibility = VISIBILITY_FULLY_TRANSPARENT;
478 }
479 Assert.assertEquals("Invalid visibility.", visibility, mScrimVisibility);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800480 }
481
482 /**
483 * Special version of ScrimController where animations have 0 duration for test purposes.
484 */
485 private class SynchronousScrimController extends ScrimController {
486
487 private FakeHandler mHandler;
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800488 private boolean mAnimationCancelled;
Lucas Dupin16cfe452018-02-08 13:14:50 -0800489 boolean mOnPreDrawCalled;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800490
Lucas Dupin3503c5f2018-03-02 19:04:00 -0800491 SynchronousScrimController(LightBarController lightBarController,
Selim Cinek99e9adf2018-03-15 09:17:47 -0700492 ScrimView scrimBehind, ScrimView scrimInFront,
Lucas Dupin82aa1632017-12-13 00:13:57 -0800493 Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters,
494 AlarmManager alarmManager) {
Selim Cinek99e9adf2018-03-15 09:17:47 -0700495 super(lightBarController, scrimBehind, scrimInFront,
Lucas Dupin82aa1632017-12-13 00:13:57 -0800496 scrimVisibleListener, dozeParameters, alarmManager);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800497 mHandler = new FakeHandler(Looper.myLooper());
498 }
499
Lucas Dupin16cfe452018-02-08 13:14:50 -0800500 @Override
501 public boolean onPreDraw() {
502 mOnPreDrawCalled = true;
503 return super.onPreDraw();
504 }
505
Lucas Dupin3503c5f2018-03-02 19:04:00 -0800506 void finishAnimationsImmediately() {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800507 boolean[] animationFinished = {false};
508 setOnAnimationFinished(()-> animationFinished[0] = true);
509
510 // Execute code that will trigger animations.
511 onPreDraw();
512
513 // Force finish screen blanking.
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800514 mHandler.dispatchQueuedMessages();
515 // Force finish all animations.
516 endAnimation(mScrimBehind, TAG_KEY_ANIM);
517 endAnimation(mScrimInFront, TAG_KEY_ANIM);
518
519 if (!animationFinished[0]) {
520 throw new IllegalStateException("Animation never finished");
521 }
522 }
523
Lucas Dupin3503c5f2018-03-02 19:04:00 -0800524 boolean wasAnimationJustCancelled() {
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800525 final boolean wasCancelled = mAnimationCancelled;
526 mAnimationCancelled = false;
527 return wasCancelled;
528 }
529
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800530 private void endAnimation(View scrimView, int tag) {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800531 Animator animator = (Animator) scrimView.getTag(tag);
532 if (animator != null) {
533 animator.end();
534 }
535 }
536
537 @Override
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800538 protected void cancelAnimator(ValueAnimator previousAnimator) {
539 super.cancelAnimator(previousAnimator);
540 mAnimationCancelled = true;
541 }
542
543 @Override
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800544 protected Handler getHandler() {
545 return mHandler;
546 }
547
548 @Override
549 protected WakeLock createWakeLock() {
550 return mWakeLock;
551 }
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800552
553 /**
554 * Do not wait for a frame since we're in a test environment.
555 * @param callback What to execute.
556 */
557 @Override
Lucas Dupin0791d972018-03-26 13:32:16 -0700558 protected void doOnTheNextFrame(Runnable callback) {
559 callback.run();
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800560 }
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800561 }
562
563}