blob: 8347fb098bd52e1e606ff4e55dc34cb4ff6f5b30 [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;
Lucas Dupin8c7cb022018-02-05 10:49:03 -080042import android.view.Choreographer;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080043import 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
56import java.util.function.Consumer;
57
58@RunWith(AndroidTestingRunner.class)
59@TestableLooper.RunWithLooper
60@SmallTest
61public class ScrimControllerTest extends SysuiTestCase {
62
63 private SynchronousScrimController mScrimController;
64 private ScrimView mScrimBehind;
65 private ScrimView mScrimInFront;
66 private View mHeadsUpScrim;
Lucas Dupin82aa1632017-12-13 00:13:57 -080067 private Consumer<Integer> mScrimVisibilityCallback;
68 private int mScrimVisibility;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080069 private LightBarController mLightBarController;
70 private DozeParameters mDozeParamenters;
71 private WakeLock mWakeLock;
72 private boolean mAlwaysOnEnabled;
Lucas Dupin82aa1632017-12-13 00:13:57 -080073 private AlarmManager mAlarmManager;
Lucas Dupin9e3fa102017-11-08 17:16:55 -080074
75 @Before
76 public void setup() {
77 mLightBarController = mock(LightBarController.class);
78 mScrimBehind = new ScrimView(getContext());
79 mScrimInFront = new ScrimView(getContext());
80 mHeadsUpScrim = mock(View.class);
81 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,
Lucas Dupin82aa1632017-12-13 00:13:57 -080089 mScrimInFront, mHeadsUpScrim, mScrimVisibilityCallback, mDozeParamenters,
90 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
173 public void transitionToBouncer() {
174 mScrimController.transitionTo(ScrimState.BOUNCER);
175 mScrimController.finishAnimationsImmediately();
176 // Front scrim should be transparent
177 // Back scrim should be visible without tint
Lucas Dupin82aa1632017-12-13 00:13:57 -0800178 assertScrimVisibility(VISIBILITY_SEMI_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800179 assertScrimTint(mScrimBehind, false /* tinted */);
180 }
181
182 @Test
183 public void transitionToUnlocked() {
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800184 mScrimController.setPanelExpansion(0f);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800185 mScrimController.transitionTo(ScrimState.UNLOCKED);
186 mScrimController.finishAnimationsImmediately();
187 // Front scrim should be transparent
188 // Back scrim should be transparent
Lucas Dupin82aa1632017-12-13 00:13:57 -0800189 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800190 assertScrimTint(mScrimBehind, false /* tinted */);
191 assertScrimTint(mScrimInFront, false /* tinted */);
192
193 // Back scrim should be visible after start dragging
194 mScrimController.setPanelExpansion(0.5f);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800195 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_SEMI_TRANSPARENT);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800196 }
197
198 @Test
199 public void transitionToUnlockedFromAod() {
200 // Simulate unlock with fingerprint
201 mScrimController.transitionTo(ScrimState.AOD);
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800202 mScrimController.setPanelExpansion(0f);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800203 mScrimController.finishAnimationsImmediately();
204 mScrimController.transitionTo(ScrimState.UNLOCKED);
205 // Immediately tinted after the transition starts
206 assertScrimTint(mScrimInFront, true /* tinted */);
207 assertScrimTint(mScrimBehind, true /* tinted */);
208 mScrimController.finishAnimationsImmediately();
209 // Front scrim should be transparent
210 // Back scrim should be transparent
211 // Neither scrims should be tinted anymore after the animation.
Lucas Dupin82aa1632017-12-13 00:13:57 -0800212 assertScrimVisibility(VISIBILITY_FULLY_TRANSPARENT, VISIBILITY_FULLY_TRANSPARENT);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800213 assertScrimTint(mScrimInFront, false /* tinted */);
214 assertScrimTint(mScrimBehind, false /* tinted */);
215 }
216
217 @Test
218 public void scrimBlanksBeforeLeavingAoD() {
219 // Simulate unlock with fingerprint
220 mScrimController.transitionTo(ScrimState.AOD);
221 mScrimController.finishAnimationsImmediately();
222 mScrimController.transitionTo(ScrimState.UNLOCKED,
223 new ScrimController.Callback() {
224 @Override
225 public void onDisplayBlanked() {
226 // Front scrim should be black in the middle of the transition
227 Assert.assertTrue("Scrim should be visible during transition. Alpha: "
228 + mScrimInFront.getViewAlpha(), mScrimInFront.getViewAlpha() > 0);
229 assertScrimTint(mScrimInFront, true /* tinted */);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800230 Assert.assertSame("Scrim should be visible during transition.",
231 mScrimVisibility, VISIBILITY_FULLY_OPAQUE);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800232 }
233 });
234 mScrimController.finishAnimationsImmediately();
235 }
236
237 @Test
238 public void testScrimCallback() {
239 int[] callOrder = {0, 0, 0};
240 int[] currentCall = {0};
241 mScrimController.transitionTo(ScrimState.AOD, new ScrimController.Callback() {
242 @Override
243 public void onStart() {
244 callOrder[0] = ++currentCall[0];
245 }
246
247 @Override
248 public void onDisplayBlanked() {
249 callOrder[1] = ++currentCall[0];
250 }
251
252 @Override
253 public void onFinished() {
254 callOrder[2] = ++currentCall[0];
255 }
256 });
257 mScrimController.finishAnimationsImmediately();
258 Assert.assertEquals("onStart called in wrong order", 1, callOrder[0]);
259 Assert.assertEquals("onDisplayBlanked called in wrong order", 2, callOrder[1]);
260 Assert.assertEquals("onFinished called in wrong order", 3, callOrder[2]);
261 }
262
263 @Test
264 public void testScrimCallbacksWithoutAmbientDisplay() {
265 mAlwaysOnEnabled = false;
266 testScrimCallback();
267 }
268
269 @Test
270 public void testScrimCallbackCancelled() {
271 boolean[] cancelledCalled = {false};
272 mScrimController.transitionTo(ScrimState.AOD, new ScrimController.Callback() {
273 @Override
274 public void onCancelled() {
275 cancelledCalled[0] = true;
276 }
277 });
278 mScrimController.transitionTo(ScrimState.PULSING);
279 Assert.assertTrue("onCancelled should have been called", cancelledCalled[0]);
280 }
281
282 @Test
Lucas Dupineea53b32017-12-18 13:47:14 -0800283 public void testHoldsWakeLock_whenAOD() {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800284 mScrimController.transitionTo(ScrimState.AOD);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800285 verify(mWakeLock).acquire();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800286 verify(mWakeLock, never()).release();
287 mScrimController.finishAnimationsImmediately();
Lucas Dupin82aa1632017-12-13 00:13:57 -0800288 verify(mWakeLock).release();
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800289 }
290
Lucas Dupin19aba8e2017-12-11 12:42:26 -0800291 @Test
Lucas Dupineea53b32017-12-18 13:47:14 -0800292 public void testDoesNotHoldWakeLock_whenUnlocking() {
293 mScrimController.transitionTo(ScrimState.UNLOCKED);
294 mScrimController.finishAnimationsImmediately();
295 verifyZeroInteractions(mWakeLock);
296 }
297
298 @Test
Lucas Dupin19aba8e2017-12-11 12:42:26 -0800299 public void testCallbackInvokedOnSameStateTransition() {
300 mScrimController.transitionTo(ScrimState.UNLOCKED);
301 mScrimController.finishAnimationsImmediately();
302 ScrimController.Callback callback = mock(ScrimController.Callback.class);
303 mScrimController.transitionTo(ScrimState.UNLOCKED, callback);
Lucas Dupin82aa1632017-12-13 00:13:57 -0800304 verify(callback).onFinished();
305 }
306
307 @Test
308 public void testHoldsAodWallpaperAnimationLock() {
309 // Pre-conditions
310 mScrimController.transitionTo(ScrimState.AOD);
311 mScrimController.finishAnimationsImmediately();
312 reset(mWakeLock);
313
314 mScrimController.onHideWallpaperTimeout();
315 verify(mWakeLock).acquire();
316 verify(mWakeLock, never()).release();
317 mScrimController.finishAnimationsImmediately();
318 verify(mWakeLock).release();
319 }
320
321 @Test
322 public void testWillHideAoDWallpaper() {
323 mScrimController.setWallpaperSupportsAmbientMode(true);
324 mScrimController.transitionTo(ScrimState.AOD);
325 verify(mAlarmManager).setExact(anyInt(), anyLong(), any(), any(), any());
326 mScrimController.transitionTo(ScrimState.KEYGUARD);
327 verify(mAlarmManager).cancel(any(AlarmManager.OnAlarmListener.class));
Lucas Dupin19aba8e2017-12-11 12:42:26 -0800328 }
329
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800330 @Test
331 public void testConservesExpansionOpacityAfterTransition() {
332 mScrimController.transitionTo(ScrimState.UNLOCKED);
333 mScrimController.setPanelExpansion(0.5f);
334 mScrimController.finishAnimationsImmediately();
335
336 final float expandedAlpha = mScrimBehind.getViewAlpha();
337
338 mScrimController.transitionTo(ScrimState.BRIGHTNESS_MIRROR);
339 mScrimController.finishAnimationsImmediately();
340 mScrimController.transitionTo(ScrimState.UNLOCKED);
341 mScrimController.finishAnimationsImmediately();
342
343 Assert.assertEquals("Scrim expansion opacity wasn't conserved when transitioning back",
344 expandedAlpha, mScrimBehind.getViewAlpha(), 0.01f);
345 }
346
347 @Test
348 public void cancelsOldAnimationBeforeBlanking() {
349 mScrimController.transitionTo(ScrimState.AOD);
350 mScrimController.finishAnimationsImmediately();
351 // Consume whatever value we had before
352 mScrimController.wasAnimationJustCancelled();
353
354 mScrimController.transitionTo(ScrimState.KEYGUARD);
355 mScrimController.finishAnimationsImmediately();
356 Assert.assertTrue(mScrimController.wasAnimationJustCancelled());
357 }
358
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800359 private void assertScrimTint(ScrimView scrimView, boolean tinted) {
360 final boolean viewIsTinted = scrimView.getTint() != Color.TRANSPARENT;
361 final String name = scrimView == mScrimInFront ? "front" : "back";
362 Assert.assertEquals("Tint test failed at state " + mScrimController.getState()
363 +" with scrim: " + name + " and tint: " + Integer.toHexString(scrimView.getTint()),
364 tinted, viewIsTinted);
365 }
366
Lucas Dupin82aa1632017-12-13 00:13:57 -0800367 private void assertScrimVisibility(int inFront, int behind) {
368 boolean inFrontVisible = inFront != ScrimController.VISIBILITY_FULLY_TRANSPARENT;
369 boolean behindVisible = behind != ScrimController.VISIBILITY_FULLY_TRANSPARENT;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800370 Assert.assertEquals("Unexpected front scrim visibility. Alpha is "
Lucas Dupin82aa1632017-12-13 00:13:57 -0800371 + mScrimInFront.getViewAlpha(), inFrontVisible, mScrimInFront.getViewAlpha() > 0);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800372 Assert.assertEquals("Unexpected back scrim visibility. Alpha is "
Lucas Dupin82aa1632017-12-13 00:13:57 -0800373 + mScrimBehind.getViewAlpha(), behindVisible, mScrimBehind.getViewAlpha() > 0);
374
375 final int visibility;
376 if (inFront == VISIBILITY_FULLY_OPAQUE || behind == VISIBILITY_FULLY_OPAQUE) {
377 visibility = VISIBILITY_FULLY_OPAQUE;
378 } else if (inFront > VISIBILITY_FULLY_TRANSPARENT || behind > VISIBILITY_FULLY_TRANSPARENT) {
379 visibility = VISIBILITY_SEMI_TRANSPARENT;
380 } else {
381 visibility = VISIBILITY_FULLY_TRANSPARENT;
382 }
383 Assert.assertEquals("Invalid visibility.", visibility, mScrimVisibility);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800384 }
385
386 /**
387 * Special version of ScrimController where animations have 0 duration for test purposes.
388 */
389 private class SynchronousScrimController extends ScrimController {
390
391 private FakeHandler mHandler;
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800392 private boolean mAnimationCancelled;
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800393
394 public SynchronousScrimController(LightBarController lightBarController,
395 ScrimView scrimBehind, ScrimView scrimInFront, View headsUpScrim,
Lucas Dupin82aa1632017-12-13 00:13:57 -0800396 Consumer<Integer> scrimVisibleListener, DozeParameters dozeParameters,
397 AlarmManager alarmManager) {
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800398 super(lightBarController, scrimBehind, scrimInFront, headsUpScrim,
Lucas Dupin82aa1632017-12-13 00:13:57 -0800399 scrimVisibleListener, dozeParameters, alarmManager);
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800400 mHandler = new FakeHandler(Looper.myLooper());
401 }
402
403 public void finishAnimationsImmediately() {
404 boolean[] animationFinished = {false};
405 setOnAnimationFinished(()-> animationFinished[0] = true);
406
407 // Execute code that will trigger animations.
408 onPreDraw();
409
410 // Force finish screen blanking.
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800411 mHandler.dispatchQueuedMessages();
412 // Force finish all animations.
413 endAnimation(mScrimBehind, TAG_KEY_ANIM);
414 endAnimation(mScrimInFront, TAG_KEY_ANIM);
415
416 if (!animationFinished[0]) {
417 throw new IllegalStateException("Animation never finished");
418 }
419 }
420
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800421 public boolean wasAnimationJustCancelled() {
422 final boolean wasCancelled = mAnimationCancelled;
423 mAnimationCancelled = false;
424 return wasCancelled;
425 }
426
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800427 private void endAnimation(ScrimView scrimView, int tag) {
428 Animator animator = (Animator) scrimView.getTag(tag);
429 if (animator != null) {
430 animator.end();
431 }
432 }
433
434 @Override
Lucas Dupin80a3fcc2018-02-07 10:49:55 -0800435 protected void cancelAnimator(ValueAnimator previousAnimator) {
436 super.cancelAnimator(previousAnimator);
437 mAnimationCancelled = true;
438 }
439
440 @Override
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800441 protected Handler getHandler() {
442 return mHandler;
443 }
444
445 @Override
446 protected WakeLock createWakeLock() {
447 return mWakeLock;
448 }
Lucas Dupin8c7cb022018-02-05 10:49:03 -0800449
450 /**
451 * Do not wait for a frame since we're in a test environment.
452 * @param callback What to execute.
453 */
454 @Override
455 protected void doOnTheNextFrame(Choreographer.FrameCallback callback) {
456 callback.doFrame(0);
457 }
Lucas Dupin9e3fa102017-11-08 17:16:55 -0800458 }
459
460}