blob: c5d4019252ff29aa20bca0c7366235edd09b5322 [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
Lyn Hanbde48202019-05-29 19:18:29 -070019import static com.android.systemui.statusbar.phone.ScrimController.OPAQUE;
20import static com.android.systemui.statusbar.phone.ScrimController.SEMI_TRANSPARENT;
21import static com.android.systemui.statusbar.phone.ScrimController.TRANSPARENT;
Lucas Dupin82aa1632017-12-13 00:13:57 -080022
23import static org.mockito.ArgumentMatchers.any;
24import static org.mockito.ArgumentMatchers.anyInt;
25import static org.mockito.ArgumentMatchers.anyLong;
Lucas Dupinee4c9b72019-02-18 17:04:58 -080026import static org.mockito.ArgumentMatchers.anyString;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080027import static org.mockito.Mockito.mock;
28import static org.mockito.Mockito.never;
Lucas Dupin82aa1632017-12-13 00:13:57 -080029import static org.mockito.Mockito.reset;
Lucas Dupin067136c2018-03-27 18:03:25 -070030import static org.mockito.Mockito.spy;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080031import static org.mockito.Mockito.verify;
Lucas Dupineea53b32017-12-18 13:47:14 -080032import static org.mockito.Mockito.verifyZeroInteractions;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080033import static org.mockito.Mockito.when;
34
35import android.animation.Animator;
Lucas Dupin80a3fcc2018-02-07 10:49:55 -080036import android.animation.ValueAnimator;
Lucas Dupin82aa1632017-12-13 00:13:57 -080037import android.app.AlarmManager;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080038import android.graphics.Color;
39import android.os.Handler;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080040import android.testing.AndroidTestingRunner;
41import android.testing.TestableLooper;
42import android.view.View;
43
Brett Chabot84151d92019-02-27 15:37:59 -080044import androidx.test.filters.SmallTest;
45
shawnlin317db372018-04-09 19:49:48 +080046import com.android.internal.colorextraction.ColorExtractor.GradientColors;
Yohei Yukawa795f0102018-04-13 14:55:30 -070047import com.android.internal.util.function.TriConsumer;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080048import com.android.systemui.SysuiTestCase;
49import com.android.systemui.statusbar.ScrimView;
Selim Cinek72cd9a72019-08-09 17:19:57 -070050import com.android.systemui.statusbar.policy.KeyguardMonitor;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080051import com.android.systemui.util.wakelock.WakeLock;
52import com.android.systemui.utils.os.FakeHandler;
53
Lucas Dupin4dbe5182019-03-07 18:20:11 -080054import org.junit.After;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080055import org.junit.Assert;
56import org.junit.Before;
57import org.junit.Test;
58import org.junit.runner.RunWith;
59
Lucas Dupin1c327432019-01-03 13:37:53 -080060import java.util.Collections;
Lucas Dupin78949b82018-04-03 18:54:39 -070061import java.util.HashSet;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080062import java.util.function.Consumer;
63
64@RunWith(AndroidTestingRunner.class)
65@TestableLooper.RunWithLooper
66@SmallTest
67public class ScrimControllerTest extends SysuiTestCase {
68
69 private SynchronousScrimController mScrimController;
70 private ScrimView mScrimBehind;
71 private ScrimView mScrimInFront;
Lyn Hanbde48202019-05-29 19:18:29 -070072 private ScrimView mScrimForBubble;
Yohei Yukawa795f0102018-04-13 14:55:30 -070073 private ScrimState mScrimState;
shawnlin317db372018-04-09 19:49:48 +080074 private float mScrimBehindAlpha;
75 private GradientColors mScrimInFrontColor;
Lucas Dupin82aa1632017-12-13 00:13:57 -080076 private int mScrimVisibility;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080077 private DozeParameters mDozeParamenters;
78 private WakeLock mWakeLock;
79 private boolean mAlwaysOnEnabled;
Lucas Dupin82aa1632017-12-13 00:13:57 -080080 private AlarmManager mAlarmManager;
Lucas Dupin54fbfb32019-03-05 18:08:13 -080081 private TestableLooper mLooper;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080082
Yohei Yukawa795f0102018-04-13 14:55:30 -070083
Lucas Dupin9e3fa102017-11-08 17:16:55 -080084 @Before
85 public void setup() {
Lucas Dupin067136c2018-03-27 18:03:25 -070086 mScrimBehind = spy(new ScrimView(getContext()));
Lucas Dupin9e3fa102017-11-08 17:16:55 -080087 mScrimInFront = new ScrimView(getContext());
Lyn Hanbde48202019-05-29 19:18:29 -070088 mScrimForBubble = new ScrimView(getContext());
Lucas Dupin9e3fa102017-11-08 17:16:55 -080089 mWakeLock = mock(WakeLock.class);
Lucas Dupin82aa1632017-12-13 00:13:57 -080090 mAlarmManager = mock(AlarmManager.class);
Lucas Dupin9e3fa102017-11-08 17:16:55 -080091 mAlwaysOnEnabled = true;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080092 mDozeParamenters = mock(DozeParameters.class);
Lucas Dupin54fbfb32019-03-05 18:08:13 -080093 mLooper = TestableLooper.get(this);
Lucas Dupin9e3fa102017-11-08 17:16:55 -080094 when(mDozeParamenters.getAlwaysOn()).thenAnswer(invocation -> mAlwaysOnEnabled);
Lucas Dupin43d0d732017-11-16 11:23:49 -080095 when(mDozeParamenters.getDisplayNeedsBlanking()).thenReturn(true);
shawnlin317db372018-04-09 19:49:48 +080096 mScrimController = new SynchronousScrimController(mScrimBehind, mScrimInFront,
Lyn Hanbde48202019-05-29 19:18:29 -070097 mScrimForBubble,
Yohei Yukawa795f0102018-04-13 14:55:30 -070098 (scrimState, scrimBehindAlpha, scrimInFrontColor) -> {
99 mScrimState = scrimState;
100 mScrimBehindAlpha = scrimBehindAlpha;
101 mScrimInFrontColor = scrimInFrontColor;
102 },
Selim Cinek72cd9a72019-08-09 17:19:57 -0700103 visible -> mScrimVisibility = visible, mDozeParamenters, mAlarmManager,
104 mock(KeyguardMonitor.class));
Lucas Dupinf8463ee2018-06-11 16:18:15 -0700105 mScrimController.setHasBackdrop(false);
TYM Tsaia71c8922019-01-07 15:57:53 +0800106 mScrimController.setWallpaperSupportsAmbientMode(false);
Lucas Dupin4dbe5182019-03-07 18:20:11 -0800107 mScrimController.transitionTo(ScrimState.KEYGUARD);
108 mScrimController.finishAnimationsImmediately();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800109 }
110
Lucas Dupin4dbe5182019-03-07 18:20:11 -0800111 @After
112 public void tearDown() {
113 mScrimController.finishAnimationsImmediately();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800114 }
115
116 @Test
117 public void transitionToKeyguard() {
118 mScrimController.transitionTo(ScrimState.KEYGUARD);
119 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700120
121 assertScrimAlpha(TRANSPARENT /* front */,
122 SEMI_TRANSPARENT /* back */,
123 TRANSPARENT /* bubble */);
124
125 assertScrimTint(true /* front */,
126 true /* behind */,
127 false /* bubble */);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800128 }
129
130 @Test
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700131 public void transitionToAod_withRegularWallpaper() {
132 mScrimController.transitionTo(ScrimState.AOD);
133 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700134
135 assertScrimAlpha(TRANSPARENT /* front */,
136 OPAQUE /* back */,
137 TRANSPARENT /* bubble */);
138
139 assertScrimTint(true /* front */,
140 true /* behind */,
141 false /* bubble */);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700142 }
143
144 @Test
145 public void transitionToAod_withAodWallpaper() {
146 mScrimController.setWallpaperSupportsAmbientMode(true);
147 mScrimController.transitionTo(ScrimState.AOD);
148 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700149
150 assertScrimAlpha(TRANSPARENT /* front */,
151 TRANSPARENT /* back */,
152 TRANSPARENT /* bubble */);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800153
Lucas Dupin00be88f2019-01-03 17:50:52 -0800154 // Pulsing notification should conserve AOD wallpaper.
Lucas Dupin82aa1632017-12-13 00:13:57 -0800155 mScrimController.transitionTo(ScrimState.PULSING);
156 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700157
158 assertScrimAlpha(TRANSPARENT /* front */,
159 TRANSPARENT /* back */,
160 TRANSPARENT /* bubble */);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700161 }
162
163 @Test
164 public void transitionToAod_withAodWallpaperAndLockScreenWallpaper() {
Lucas Dupinf8463ee2018-06-11 16:18:15 -0700165 mScrimController.setHasBackdrop(true);
Lucas Dupin7517b5d2017-08-22 12:51:25 -0700166 mScrimController.setWallpaperSupportsAmbientMode(true);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800167 mScrimController.transitionTo(ScrimState.AOD);
168 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700169
170 assertScrimAlpha(TRANSPARENT /* front */,
171 OPAQUE /* back */,
172 TRANSPARENT /* bubble */);
173
174 assertScrimTint(true /* front */,
175 true /* behind */,
176 false /* bubble */);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800177 }
178
179 @Test
Lucas Dupin9bee5822018-07-09 14:32:53 -0700180 public void setHasBackdrop_withAodWallpaperAndAlbumArt() {
181 mScrimController.setWallpaperSupportsAmbientMode(true);
182 mScrimController.transitionTo(ScrimState.AOD);
183 mScrimController.finishAnimationsImmediately();
184 mScrimController.setHasBackdrop(true);
185 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700186
187 assertScrimAlpha(TRANSPARENT /* front */,
188 OPAQUE /* back */,
189 TRANSPARENT /* bubble */);
190
191 assertScrimTint(true /* front */,
192 true /* behind */,
193 false /* bubble */);
Lucas Dupin9bee5822018-07-09 14:32:53 -0700194 }
195
196 @Test
Michael Wrightcae88752018-04-16 23:13:54 +0100197 public void transitionToAod_withFrontAlphaUpdates() {
198 // Assert that setting the AOD front scrim alpha doesn't take effect in a non-AOD state.
199 mScrimController.transitionTo(ScrimState.KEYGUARD);
200 mScrimController.setAodFrontScrimAlpha(0.5f);
201 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700202
203 assertScrimAlpha(TRANSPARENT /* front */,
204 SEMI_TRANSPARENT /* back */,
205 TRANSPARENT /* bubble */);
Michael Wrightcae88752018-04-16 23:13:54 +0100206
207 // ... but that it does take effect once we enter the AOD state.
208 mScrimController.transitionTo(ScrimState.AOD);
209 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700210 assertScrimAlpha(SEMI_TRANSPARENT /* front */,
211 OPAQUE /* back */,
212 TRANSPARENT /* bubble */);
Michael Wrightcae88752018-04-16 23:13:54 +0100213
214 // ... and that if we set it while we're in AOD, it does take immediate effect.
215 mScrimController.setAodFrontScrimAlpha(1f);
Lyn Hanbde48202019-05-29 19:18:29 -0700216 assertScrimAlpha(OPAQUE /* front */,
217 OPAQUE /* back */,
218 TRANSPARENT /* bubble */);
Michael Wrightcae88752018-04-16 23:13:54 +0100219
220 // ... and make sure we recall the previous front scrim alpha even if we transition away
221 // for a bit.
222 mScrimController.transitionTo(ScrimState.UNLOCKED);
223 mScrimController.transitionTo(ScrimState.AOD);
224 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700225 assertScrimAlpha(OPAQUE /* front */,
226 OPAQUE /* back */,
227 TRANSPARENT /* bubble */);
Michael Wrightcae88752018-04-16 23:13:54 +0100228
Lucas Dupin69bda602018-05-18 17:24:52 -0700229 // ... and alpha updates should be completely ignored if always_on is off.
230 // Passing it forward would mess up the wake-up transition.
231 mAlwaysOnEnabled = false;
232 mScrimController.transitionTo(ScrimState.UNLOCKED);
233 mScrimController.transitionTo(ScrimState.AOD);
234 mScrimController.finishAnimationsImmediately();
235 mScrimController.setAodFrontScrimAlpha(0.3f);
236 Assert.assertEquals(ScrimState.AOD.getFrontAlpha(), mScrimInFront.getViewAlpha(), 0.001f);
237 Assert.assertNotEquals(0.3f, mScrimInFront.getViewAlpha(), 0.001f);
238
Michael Wrightcae88752018-04-16 23:13:54 +0100239 // Reset value since enums are static.
240 mScrimController.setAodFrontScrimAlpha(0f);
241 }
242
243 @Test
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800244 public void transitionToPulsing() {
Lucas Dupin82aa1632017-12-13 00:13:57 -0800245 // Pre-condition
246 // Need to go to AoD first because PULSING doesn't change
247 // the back scrim opacity - otherwise it would hide AoD wallpapers.
248 mScrimController.setWallpaperSupportsAmbientMode(false);
249 mScrimController.transitionTo(ScrimState.AOD);
250 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700251 assertScrimAlpha(TRANSPARENT /* front */,
252 OPAQUE /* back */,
253 TRANSPARENT /* bubble */);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800254
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800255 mScrimController.transitionTo(ScrimState.PULSING);
256 mScrimController.finishAnimationsImmediately();
Lucas Dupina7eacf92019-07-24 12:40:34 -0700257 // Front scrim should be transparent, but tinted
Lucas Dupinde64ee02018-12-21 14:45:12 -0800258 // Back scrim should be semi-transparent so the user can see the wallpaper
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800259 // Pulse callback should have been invoked
Lyn Hanbde48202019-05-29 19:18:29 -0700260 assertScrimAlpha(TRANSPARENT /* front */,
261 OPAQUE /* back */,
262 TRANSPARENT /* bubble */);
263
Mady Mellor4035ef52019-07-25 11:10:02 -0700264 assertScrimTint(true /* front */,
Lyn Hanbde48202019-05-29 19:18:29 -0700265 true /* behind */,
266 false /* bubble */);
Lucas Dupin5f00fa52019-03-27 22:46:53 -0700267
268 mScrimController.setWakeLockScreenSensorActive(true);
269 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700270 assertScrimAlpha(TRANSPARENT /* front */,
271 SEMI_TRANSPARENT /* back */,
272 TRANSPARENT /* bubble */);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800273 }
274
275 @Test
Lucas Dupinbc9aac12018-03-04 20:18:15 -0800276 public void transitionToKeyguardBouncer() {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800277 mScrimController.transitionTo(ScrimState.BOUNCER);
278 mScrimController.finishAnimationsImmediately();
279 // Front scrim should be transparent
280 // Back scrim should be visible without tint
Lyn Hanbde48202019-05-29 19:18:29 -0700281 assertScrimAlpha(TRANSPARENT /* front */,
282 SEMI_TRANSPARENT /* back */,
283 TRANSPARENT /* bubble */);
284
285 assertScrimTint(false /* front */,
286 false /* behind */,
287 false /* bubble */);
Lucas Dupinbc9aac12018-03-04 20:18:15 -0800288 }
289
290 @Test
291 public void transitionToBouncer() {
Lucas Dupin05726cd2018-03-13 14:00:24 -0700292 mScrimController.transitionTo(ScrimState.BOUNCER_SCRIMMED);
Lucas Dupinbc9aac12018-03-04 20:18:15 -0800293 mScrimController.finishAnimationsImmediately();
294 // Front scrim should be transparent
295 // Back scrim should be visible without tint
Lyn Hanbde48202019-05-29 19:18:29 -0700296 assertScrimAlpha(SEMI_TRANSPARENT /* front */,
297 TRANSPARENT /* back */,
298 TRANSPARENT /* bubble */);
299 assertScrimTint(false /* front */,
300 false /* behind */,
301 false /* bubble */);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800302 }
303
304 @Test
305 public void transitionToUnlocked() {
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800306 mScrimController.setPanelExpansion(0f);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800307 mScrimController.transitionTo(ScrimState.UNLOCKED);
308 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700309 assertScrimAlpha(TRANSPARENT /* front */,
310 TRANSPARENT /* back */,
311 TRANSPARENT /* bubble */);
312
313 assertScrimTint(false /* front */,
314 false /* behind */,
315 false /* bubble */);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800316
317 // Back scrim should be visible after start dragging
318 mScrimController.setPanelExpansion(0.5f);
Lyn Hanbde48202019-05-29 19:18:29 -0700319 assertScrimAlpha(TRANSPARENT /* front */,
320 SEMI_TRANSPARENT /* back */,
321 TRANSPARENT /* bubble */);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800322 }
323
324 @Test
Mady Mellor0c333772018-11-06 18:05:54 -0800325 public void transitionToBubbleExpanded() {
326 mScrimController.transitionTo(ScrimState.BUBBLE_EXPANDED);
327 mScrimController.finishAnimationsImmediately();
328
Lyn Hanbde48202019-05-29 19:18:29 -0700329 assertScrimTint(false /* front */,
330 false /* behind */,
331 false /* bubble */);
332
Mady Mellor0c333772018-11-06 18:05:54 -0800333 // Front scrim should be transparent
Lyn Hanbde48202019-05-29 19:18:29 -0700334 Assert.assertEquals(ScrimController.TRANSPARENT,
Mady Mellor0c333772018-11-06 18:05:54 -0800335 mScrimInFront.getViewAlpha(), 0.0f);
336 // Back scrim should be visible
337 Assert.assertEquals(ScrimController.GRADIENT_SCRIM_ALPHA_BUSY,
338 mScrimBehind.getViewAlpha(), 0.0f);
Lyn Hanbde48202019-05-29 19:18:29 -0700339 // Bubble scrim should be visible
340 Assert.assertEquals(ScrimController.GRADIENT_SCRIM_ALPHA_BUSY,
341 mScrimBehind.getViewAlpha(), 0.0f);
Mady Mellor0c333772018-11-06 18:05:54 -0800342 }
343
344 @Test
Yohei Yukawa795f0102018-04-13 14:55:30 -0700345 public void scrimStateCallback() {
346 mScrimController.transitionTo(ScrimState.UNLOCKED);
347 mScrimController.finishAnimationsImmediately();
348 Assert.assertEquals(mScrimState, ScrimState.UNLOCKED);
349
350 mScrimController.transitionTo(ScrimState.BOUNCER);
351 mScrimController.finishAnimationsImmediately();
352 Assert.assertEquals(mScrimState, ScrimState.BOUNCER);
353
354 mScrimController.transitionTo(ScrimState.BOUNCER_SCRIMMED);
355 mScrimController.finishAnimationsImmediately();
356 Assert.assertEquals(mScrimState, ScrimState.BOUNCER_SCRIMMED);
357 }
358
359 @Test
shawnlin317db372018-04-09 19:49:48 +0800360 public void panelExpansion() {
361 mScrimController.setPanelExpansion(0f);
362 mScrimController.setPanelExpansion(0.5f);
363 mScrimController.transitionTo(ScrimState.UNLOCKED);
364 mScrimController.finishAnimationsImmediately();
365
366 reset(mScrimBehind);
367 mScrimController.setPanelExpansion(0f);
368 mScrimController.setPanelExpansion(1.0f);
Lucas Dupin4dbe5182019-03-07 18:20:11 -0800369 mScrimController.finishAnimationsImmediately();
shawnlin317db372018-04-09 19:49:48 +0800370
371 Assert.assertEquals("Scrim alpha should change after setPanelExpansion",
372 mScrimBehindAlpha, mScrimBehind.getViewAlpha(), 0.01f);
373
374 mScrimController.setPanelExpansion(0f);
Lucas Dupin4dbe5182019-03-07 18:20:11 -0800375 mScrimController.finishAnimationsImmediately();
shawnlin317db372018-04-09 19:49:48 +0800376
377 Assert.assertEquals("Scrim alpha should change after setPanelExpansion",
378 mScrimBehindAlpha, mScrimBehind.getViewAlpha(), 0.01f);
379 }
380
381 @Test
Lucas Dupin67f02632018-03-12 11:08:31 -0700382 public void panelExpansionAffectsAlpha() {
383 mScrimController.setPanelExpansion(0f);
384 mScrimController.setPanelExpansion(0.5f);
385 mScrimController.transitionTo(ScrimState.UNLOCKED);
386 mScrimController.finishAnimationsImmediately();
387
388 final float scrimAlpha = mScrimBehind.getViewAlpha();
Lucas Dupin067136c2018-03-27 18:03:25 -0700389 reset(mScrimBehind);
Lucas Dupin67f02632018-03-12 11:08:31 -0700390 mScrimController.setExpansionAffectsAlpha(false);
391 mScrimController.setPanelExpansion(0.8f);
Lucas Dupin067136c2018-03-27 18:03:25 -0700392 verifyZeroInteractions(mScrimBehind);
Lucas Dupin67f02632018-03-12 11:08:31 -0700393 Assert.assertEquals("Scrim opacity shouldn't change when setExpansionAffectsAlpha "
394 + "is false", scrimAlpha, mScrimBehind.getViewAlpha(), 0.01f);
395
396 mScrimController.setExpansionAffectsAlpha(true);
397 mScrimController.setPanelExpansion(0.1f);
Lucas Dupin4dbe5182019-03-07 18:20:11 -0800398 mScrimController.finishAnimationsImmediately();
Lucas Dupin67f02632018-03-12 11:08:31 -0700399 Assert.assertNotEquals("Scrim opacity should change when setExpansionAffectsAlpha "
400 + "is true", scrimAlpha, mScrimBehind.getViewAlpha(), 0.01f);
401 }
402
403 @Test
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800404 public void transitionToUnlockedFromAod() {
405 // Simulate unlock with fingerprint
406 mScrimController.transitionTo(ScrimState.AOD);
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800407 mScrimController.setPanelExpansion(0f);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800408 mScrimController.finishAnimationsImmediately();
409 mScrimController.transitionTo(ScrimState.UNLOCKED);
Lyn Hanbde48202019-05-29 19:18:29 -0700410
411 // Immediately tinted black after the transition starts
412 assertScrimTint(true /* front */,
413 true /* behind */,
414 true /* bubble */);
415
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800416 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700417
418 // All scrims should be transparent at the end of fade transition.
419 assertScrimAlpha(TRANSPARENT /* front */,
420 TRANSPARENT /* behind */,
421 TRANSPARENT /* bubble */);
422
423 assertScrimTint(false /* front */,
424 false /* behind */,
425 false /* bubble */);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800426 }
427
428 @Test
Lucas Dupinea0116e2018-04-05 10:09:29 -0700429 public void scrimBlanksBeforeLeavingAod() {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800430 // Simulate unlock with fingerprint
431 mScrimController.transitionTo(ScrimState.AOD);
432 mScrimController.finishAnimationsImmediately();
433 mScrimController.transitionTo(ScrimState.UNLOCKED,
434 new ScrimController.Callback() {
435 @Override
436 public void onDisplayBlanked() {
437 // Front scrim should be black in the middle of the transition
438 Assert.assertTrue("Scrim should be visible during transition. Alpha: "
439 + mScrimInFront.getViewAlpha(), mScrimInFront.getViewAlpha() > 0);
Lyn Hanbde48202019-05-29 19:18:29 -0700440 assertScrimTint(true /* front */,
441 true /* behind */,
442 true /* bubble */);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800443 Assert.assertSame("Scrim should be visible during transition.",
Lyn Hanbde48202019-05-29 19:18:29 -0700444 mScrimVisibility, OPAQUE);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800445 }
446 });
447 mScrimController.finishAnimationsImmediately();
448 }
449
450 @Test
Lucas Dupineb840ea2018-06-01 00:28:58 -0700451 public void scrimBlanksWhenUnlockingFromPulse() {
452 boolean[] blanked = {false};
453 // Simulate unlock with fingerprint
454 mScrimController.transitionTo(ScrimState.PULSING);
455 mScrimController.finishAnimationsImmediately();
456 mScrimController.transitionTo(ScrimState.UNLOCKED,
457 new ScrimController.Callback() {
458 @Override
459 public void onDisplayBlanked() {
460 blanked[0] = true;
461 }
462 });
463 mScrimController.finishAnimationsImmediately();
464 Assert.assertTrue("Scrim should blank when unlocking from pulse.", blanked[0]);
465 }
466
467 @Test
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800468 public void testScrimCallback() {
469 int[] callOrder = {0, 0, 0};
470 int[] currentCall = {0};
471 mScrimController.transitionTo(ScrimState.AOD, new ScrimController.Callback() {
472 @Override
473 public void onStart() {
474 callOrder[0] = ++currentCall[0];
475 }
476
477 @Override
478 public void onDisplayBlanked() {
479 callOrder[1] = ++currentCall[0];
480 }
481
482 @Override
483 public void onFinished() {
484 callOrder[2] = ++currentCall[0];
485 }
486 });
487 mScrimController.finishAnimationsImmediately();
488 Assert.assertEquals("onStart called in wrong order", 1, callOrder[0]);
489 Assert.assertEquals("onDisplayBlanked called in wrong order", 2, callOrder[1]);
490 Assert.assertEquals("onFinished called in wrong order", 3, callOrder[2]);
491 }
492
493 @Test
494 public void testScrimCallbacksWithoutAmbientDisplay() {
495 mAlwaysOnEnabled = false;
496 testScrimCallback();
497 }
498
499 @Test
500 public void testScrimCallbackCancelled() {
501 boolean[] cancelledCalled = {false};
502 mScrimController.transitionTo(ScrimState.AOD, new ScrimController.Callback() {
503 @Override
504 public void onCancelled() {
505 cancelledCalled[0] = true;
506 }
507 });
508 mScrimController.transitionTo(ScrimState.PULSING);
509 Assert.assertTrue("onCancelled should have been called", cancelledCalled[0]);
510 }
511
512 @Test
Lucas Dupineea53b32017-12-18 13:47:14 -0800513 public void testHoldsWakeLock_whenAOD() {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800514 mScrimController.transitionTo(ScrimState.AOD);
Lucas Dupinee4c9b72019-02-18 17:04:58 -0800515 verify(mWakeLock).acquire(anyString());
516 verify(mWakeLock, never()).release(anyString());
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800517 mScrimController.finishAnimationsImmediately();
Lucas Dupinee4c9b72019-02-18 17:04:58 -0800518 verify(mWakeLock).release(anyString());
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800519 }
520
Lucas Dupin19aba8e2017-12-11 12:42:26 -0800521 @Test
Lucas Dupineea53b32017-12-18 13:47:14 -0800522 public void testDoesNotHoldWakeLock_whenUnlocking() {
523 mScrimController.transitionTo(ScrimState.UNLOCKED);
524 mScrimController.finishAnimationsImmediately();
525 verifyZeroInteractions(mWakeLock);
526 }
527
528 @Test
Lucas Dupin19aba8e2017-12-11 12:42:26 -0800529 public void testCallbackInvokedOnSameStateTransition() {
530 mScrimController.transitionTo(ScrimState.UNLOCKED);
531 mScrimController.finishAnimationsImmediately();
532 ScrimController.Callback callback = mock(ScrimController.Callback.class);
533 mScrimController.transitionTo(ScrimState.UNLOCKED, callback);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800534 verify(callback).onFinished();
535 }
536
537 @Test
538 public void testHoldsAodWallpaperAnimationLock() {
539 // Pre-conditions
540 mScrimController.transitionTo(ScrimState.AOD);
541 mScrimController.finishAnimationsImmediately();
542 reset(mWakeLock);
543
544 mScrimController.onHideWallpaperTimeout();
Lucas Dupinee4c9b72019-02-18 17:04:58 -0800545 verify(mWakeLock).acquire(anyString());
546 verify(mWakeLock, never()).release(anyString());
Lucas Dupin82aa1632017-12-13 00:13:57 -0800547 mScrimController.finishAnimationsImmediately();
Lucas Dupinee4c9b72019-02-18 17:04:58 -0800548 verify(mWakeLock).release(anyString());
Lucas Dupin82aa1632017-12-13 00:13:57 -0800549 }
550
551 @Test
TYM Tsaia71c8922019-01-07 15:57:53 +0800552 public void testHoldsPulsingWallpaperAnimationLock() {
553 // Pre-conditions
Lucas Dupin00be88f2019-01-03 17:50:52 -0800554 mScrimController.transitionTo(ScrimState.PULSING);
TYM Tsaia71c8922019-01-07 15:57:53 +0800555 mScrimController.finishAnimationsImmediately();
556 reset(mWakeLock);
557
558 mScrimController.onHideWallpaperTimeout();
Lucas Dupinee4c9b72019-02-18 17:04:58 -0800559 verify(mWakeLock).acquire(anyString());
560 verify(mWakeLock, never()).release(anyString());
TYM Tsaia71c8922019-01-07 15:57:53 +0800561 mScrimController.finishAnimationsImmediately();
Lucas Dupinee4c9b72019-02-18 17:04:58 -0800562 verify(mWakeLock).release(anyString());
TYM Tsaia71c8922019-01-07 15:57:53 +0800563 }
564
565 @Test
Lucas Dupin16cfe452018-02-08 13:14:50 -0800566 public void testWillHideAodWallpaper() {
Lucas Dupin82aa1632017-12-13 00:13:57 -0800567 mScrimController.setWallpaperSupportsAmbientMode(true);
568 mScrimController.transitionTo(ScrimState.AOD);
569 verify(mAlarmManager).setExact(anyInt(), anyLong(), any(), any(), any());
570 mScrimController.transitionTo(ScrimState.KEYGUARD);
571 verify(mAlarmManager).cancel(any(AlarmManager.OnAlarmListener.class));
Lucas Dupin19aba8e2017-12-11 12:42:26 -0800572 }
573
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800574 @Test
Jerry Changbde4c0c2019-06-13 16:58:41 +0800575 public void transitionToPulsing_withTimeoutWallpaperCallback_willHideWallpaper() {
576 mScrimController.setWallpaperSupportsAmbientMode(true);
577
578 mScrimController.transitionTo(ScrimState.PULSING, new ScrimController.Callback() {
579 @Override
580 public boolean shouldTimeoutWallpaper() {
581 return true;
582 }
583 });
584
585 verify(mAlarmManager).setExact(anyInt(), anyLong(), any(), any(), any());
586 }
587
588 @Test
589 public void transitionToPulsing_withDefaultCallback_wontHideWallpaper() {
590 mScrimController.setWallpaperSupportsAmbientMode(true);
591
592 mScrimController.transitionTo(ScrimState.PULSING, new ScrimController.Callback() {});
593
594 verify(mAlarmManager, never()).setExact(anyInt(), anyLong(), any(), any(), any());
595 }
596
597 @Test
598 public void transitionToPulsing_withoutCallback_wontHideWallpaper() {
599 mScrimController.setWallpaperSupportsAmbientMode(true);
600
601 mScrimController.transitionTo(ScrimState.PULSING);
602
603 verify(mAlarmManager, never()).setExact(anyInt(), anyLong(), any(), any(), any());
604 }
605
606 @Test
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800607 public void testConservesExpansionOpacityAfterTransition() {
608 mScrimController.transitionTo(ScrimState.UNLOCKED);
609 mScrimController.setPanelExpansion(0.5f);
610 mScrimController.finishAnimationsImmediately();
611
612 final float expandedAlpha = mScrimBehind.getViewAlpha();
613
614 mScrimController.transitionTo(ScrimState.BRIGHTNESS_MIRROR);
615 mScrimController.finishAnimationsImmediately();
616 mScrimController.transitionTo(ScrimState.UNLOCKED);
617 mScrimController.finishAnimationsImmediately();
618
619 Assert.assertEquals("Scrim expansion opacity wasn't conserved when transitioning back",
620 expandedAlpha, mScrimBehind.getViewAlpha(), 0.01f);
621 }
622
623 @Test
624 public void cancelsOldAnimationBeforeBlanking() {
625 mScrimController.transitionTo(ScrimState.AOD);
626 mScrimController.finishAnimationsImmediately();
627 // Consume whatever value we had before
628 mScrimController.wasAnimationJustCancelled();
629
630 mScrimController.transitionTo(ScrimState.KEYGUARD);
631 mScrimController.finishAnimationsImmediately();
632 Assert.assertTrue(mScrimController.wasAnimationJustCancelled());
633 }
634
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800635 @Test
Lucas Dupin38962d72018-03-14 12:41:39 -0700636 public void testScrimFocus() {
637 mScrimController.transitionTo(ScrimState.AOD);
638 Assert.assertFalse("Should not be focusable on AOD", mScrimBehind.isFocusable());
639 Assert.assertFalse("Should not be focusable on AOD", mScrimInFront.isFocusable());
640
641 mScrimController.transitionTo(ScrimState.KEYGUARD);
642 Assert.assertTrue("Should be focusable on keyguard", mScrimBehind.isFocusable());
643 Assert.assertTrue("Should be focusable on keyguard", mScrimInFront.isFocusable());
644 }
645
Lucas Dupind5107302018-03-19 15:30:29 -0700646 @Test
647 public void testHidesShowWhenLockedActivity() {
648 mScrimController.setWallpaperSupportsAmbientMode(true);
649 mScrimController.setKeyguardOccluded(true);
650 mScrimController.transitionTo(ScrimState.AOD);
651 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700652 assertScrimAlpha(TRANSPARENT /* front */,
653 OPAQUE /* behind */,
654 TRANSPARENT /* bubble */);
Lucas Dupind5107302018-03-19 15:30:29 -0700655
656 mScrimController.transitionTo(ScrimState.PULSING);
657 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700658 assertScrimAlpha(TRANSPARENT /* front */,
659 OPAQUE /* behind */,
660 TRANSPARENT /* bubble */);
Lucas Dupind5107302018-03-19 15:30:29 -0700661 }
662
Lucas Dupin78949b82018-04-03 18:54:39 -0700663 @Test
Lucas Dupin63d72172018-06-06 11:42:55 -0700664 public void testHidesShowWhenLockedActivity_whenAlreadyInAod() {
665 mScrimController.setWallpaperSupportsAmbientMode(true);
666 mScrimController.transitionTo(ScrimState.AOD);
667 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700668 assertScrimAlpha(TRANSPARENT /* front */,
669 TRANSPARENT /* behind */,
670 TRANSPARENT /* bubble */);
Lucas Dupin63d72172018-06-06 11:42:55 -0700671
672 mScrimController.setKeyguardOccluded(true);
673 mScrimController.finishAnimationsImmediately();
Lyn Hanbde48202019-05-29 19:18:29 -0700674 assertScrimAlpha(TRANSPARENT /* front */,
675 OPAQUE /* behind */,
676 TRANSPARENT /* bubble */);
Lucas Dupin63d72172018-06-06 11:42:55 -0700677 }
678
679 @Test
Lucas Dupin78949b82018-04-03 18:54:39 -0700680 public void testEatsTouchEvent() {
681 HashSet<ScrimState> eatsTouches =
Lucas Dupin1c327432019-01-03 13:37:53 -0800682 new HashSet<>(Collections.singletonList(ScrimState.AOD));
Lucas Dupin78949b82018-04-03 18:54:39 -0700683 for (ScrimState state : ScrimState.values()) {
684 if (state == ScrimState.UNINITIALIZED) {
685 continue;
686 }
687 mScrimController.transitionTo(state);
688 mScrimController.finishAnimationsImmediately();
689 Assert.assertEquals("Should be clickable unless AOD or PULSING, was: " + state,
690 mScrimBehind.getViewAlpha() != 0 && !eatsTouches.contains(state),
691 mScrimBehind.isClickable());
692 }
693 }
694
Lucas Dupinea0116e2018-04-05 10:09:29 -0700695 @Test
696 public void testAnimatesTransitionToAod() {
697 when(mDozeParamenters.shouldControlScreenOff()).thenReturn(false);
698 ScrimState.AOD.prepare(ScrimState.KEYGUARD);
699 Assert.assertFalse("No animation when ColorFade kicks in",
700 ScrimState.AOD.getAnimateChange());
701
702 reset(mDozeParamenters);
703 when(mDozeParamenters.shouldControlScreenOff()).thenReturn(true);
704 ScrimState.AOD.prepare(ScrimState.KEYGUARD);
705 Assert.assertTrue("Animate scrims when ColorFade won't be triggered",
706 ScrimState.AOD.getAnimateChange());
707 }
708
Lucas Dupin373356b2018-04-07 10:50:25 -0700709 @Test
710 public void testViewsDontHaveFocusHighlight() {
711 Assert.assertFalse("Scrim shouldn't have focus highlight",
712 mScrimInFront.getDefaultFocusHighlightEnabled());
713 Assert.assertFalse("Scrim shouldn't have focus highlight",
714 mScrimBehind.getDefaultFocusHighlightEnabled());
Lyn Hanbde48202019-05-29 19:18:29 -0700715 Assert.assertFalse("Scrim shouldn't have focus highlight",
716 mScrimForBubble.getDefaultFocusHighlightEnabled());
Lucas Dupin373356b2018-04-07 10:50:25 -0700717 }
718
Lyn Hanbde48202019-05-29 19:18:29 -0700719 private void assertScrimTint(boolean front, boolean behind, boolean bubble) {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800720 Assert.assertEquals("Tint test failed at state " + mScrimController.getState()
Lyn Hanbde48202019-05-29 19:18:29 -0700721 + " with scrim: " + getScrimName(mScrimInFront) + " and tint: "
722 + Integer.toHexString(mScrimInFront.getTint()),
723 front, mScrimInFront.getTint() != Color.TRANSPARENT);
724
725 Assert.assertEquals("Tint test failed at state " + mScrimController.getState()
726 + " with scrim: " + getScrimName(mScrimBehind) + " and tint: "
727 + Integer.toHexString(mScrimBehind.getTint()),
728 behind, mScrimBehind.getTint() != Color.TRANSPARENT);
729
730 Assert.assertEquals("Tint test failed at state " + mScrimController.getState()
731 + " with scrim: " + getScrimName(mScrimForBubble) + " and tint: "
732 + Integer.toHexString(mScrimForBubble.getTint()),
733 bubble, mScrimForBubble.getTint() != Color.TRANSPARENT);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800734 }
735
Lyn Hanbde48202019-05-29 19:18:29 -0700736 private String getScrimName(ScrimView scrim) {
737 if (scrim == mScrimInFront) {
738 return "front";
739 } else if (scrim == mScrimBehind) {
740 return "back";
741 } else if (scrim == mScrimForBubble) {
742 return "bubble";
Lucas Dupin82aa1632017-12-13 00:13:57 -0800743 }
Lyn Hanbde48202019-05-29 19:18:29 -0700744 return "unknown_scrim";
745 }
746
747 private void assertScrimAlpha(int front, int behind, int bubble) {
748 // Check single scrim visibility.
749 Assert.assertEquals("Unexpected front scrim alpha: "
750 + mScrimInFront.getViewAlpha(),
751 front != TRANSPARENT /* expected */,
752 mScrimInFront.getViewAlpha() > TRANSPARENT /* actual */);
753
754 Assert.assertEquals("Unexpected back scrim alpha: "
755 + mScrimBehind.getViewAlpha(),
756 behind != TRANSPARENT /* expected */,
757 mScrimBehind.getViewAlpha() > TRANSPARENT /* actual */);
758
759 Assert.assertEquals(
760 "Unexpected bubble scrim alpha: "
761 + mScrimForBubble.getViewAlpha(), /* message */
762 bubble != TRANSPARENT /* expected */,
763 mScrimForBubble.getViewAlpha() > TRANSPARENT /* actual */);
764
765 // Check combined scrim visibility.
766 final int visibility;
767 if (front == OPAQUE || behind == OPAQUE || bubble == OPAQUE) {
768 visibility = OPAQUE;
769 } else if (front > TRANSPARENT || behind > TRANSPARENT || bubble > TRANSPARENT) {
770 visibility = SEMI_TRANSPARENT;
771 } else {
772 visibility = TRANSPARENT;
773 }
774 Assert.assertEquals("Invalid visibility.",
775 visibility /* expected */,
776 mScrimVisibility);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800777 }
778
779 /**
780 * Special version of ScrimController where animations have 0 duration for test purposes.
781 */
782 private class SynchronousScrimController extends ScrimController {
783
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800784 private boolean mAnimationCancelled;
Lucas Dupin16cfe452018-02-08 13:14:50 -0800785 boolean mOnPreDrawCalled;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800786
shawnlin317db372018-04-09 19:49:48 +0800787 SynchronousScrimController(ScrimView scrimBehind, ScrimView scrimInFront,
Lyn Hanbde48202019-05-29 19:18:29 -0700788 ScrimView scrimForBubble,
Yohei Yukawa795f0102018-04-13 14:55:30 -0700789 TriConsumer<ScrimState, Float, GradientColors> scrimStateListener,
Lucas Dupin82aa1632017-12-13 00:13:57 -0800790 Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters,
Selim Cinek72cd9a72019-08-09 17:19:57 -0700791 AlarmManager alarmManager, KeyguardMonitor keyguardMonitor) {
Lyn Hanbde48202019-05-29 19:18:29 -0700792 super(scrimBehind, scrimInFront, scrimForBubble, scrimStateListener,
Mady Mellor06792002019-08-13 14:33:24 -0700793 scrimVisibleListener, dozeParameters, alarmManager, keyguardMonitor);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800794 }
795
Lucas Dupin16cfe452018-02-08 13:14:50 -0800796 @Override
797 public boolean onPreDraw() {
798 mOnPreDrawCalled = true;
799 return super.onPreDraw();
800 }
801
Lucas Dupin3503c5f2018-03-02 19:04:00 -0800802 void finishAnimationsImmediately() {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800803 boolean[] animationFinished = {false};
Lyn Hanbde48202019-05-29 19:18:29 -0700804 setOnAnimationFinished(() -> animationFinished[0] = true);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800805 // Execute code that will trigger animations.
806 onPreDraw();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800807 // Force finish all animations.
Lucas Dupin54fbfb32019-03-05 18:08:13 -0800808 mLooper.processAllMessages();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800809 endAnimation(mScrimBehind, TAG_KEY_ANIM);
810 endAnimation(mScrimInFront, TAG_KEY_ANIM);
Lyn Hanbde48202019-05-29 19:18:29 -0700811 endAnimation(mScrimForBubble, TAG_KEY_ANIM);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800812
813 if (!animationFinished[0]) {
814 throw new IllegalStateException("Animation never finished");
815 }
816 }
817
Lucas Dupin3503c5f2018-03-02 19:04:00 -0800818 boolean wasAnimationJustCancelled() {
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800819 final boolean wasCancelled = mAnimationCancelled;
820 mAnimationCancelled = false;
821 return wasCancelled;
822 }
823
Lucas Dupin3daf3b02018-02-27 17:23:41 -0800824 private void endAnimation(View scrimView, int tag) {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800825 Animator animator = (Animator) scrimView.getTag(tag);
826 if (animator != null) {
827 animator.end();
828 }
829 }
830
831 @Override
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800832 protected void cancelAnimator(ValueAnimator previousAnimator) {
833 super.cancelAnimator(previousAnimator);
834 mAnimationCancelled = true;
835 }
836
837 @Override
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800838 protected Handler getHandler() {
Lucas Dupin54fbfb32019-03-05 18:08:13 -0800839 return new FakeHandler(mLooper.getLooper());
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800840 }
841
842 @Override
843 protected WakeLock createWakeLock() {
844 return mWakeLock;
845 }
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800846
847 /**
848 * Do not wait for a frame since we're in a test environment.
Lyn Hanbde48202019-05-29 19:18:29 -0700849 *
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800850 * @param callback What to execute.
851 */
852 @Override
Lucas Dupin0791d972018-03-26 13:32:16 -0700853 protected void doOnTheNextFrame(Runnable callback) {
854 callback.run();
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800855 }
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800856 }
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800857}