Implement updated low light animations
The transition between low light and the user dream is currently the only dream to dream transition. The prior dream does not get any time to play animations as the default dream transition is played as soon as the new dream starts. This change allows an animation to play before setting the system dream to low light for a smooth transition. The overlay exit animation is reintroduced from ag/20377749. The animation was removed since transitions between dreams and core SysUI components is now centrally controlled by keyguard. Since this transition is between two dreams, keyguard is not able to coordinate. Screen capture from device: http://screencast/cast/NDU0NzAyNjIyMzEwNDAwMHwyNmU0ZWExNy0xNg Bug: 260638159 Test: atest LowLightTransitionCoordinatorTest LowLightDreamManagerTest DreamOverlayAnimationsControllerTest DreamOverlayContainerViewControllerTest Change-Id: Ib38a8848ea6361d3d6ef267f2f3a84d3daf6711d
This commit is contained in:
@@ -72,6 +72,7 @@ public final class LowLightDreamManager {
|
||||
public static final int AMBIENT_LIGHT_MODE_LOW_LIGHT = 2;
|
||||
|
||||
private final DreamManager mDreamManager;
|
||||
private final LowLightTransitionCoordinator mLowLightTransitionCoordinator;
|
||||
|
||||
@Nullable
|
||||
private final ComponentName mLowLightDreamComponent;
|
||||
@@ -81,8 +82,10 @@ public final class LowLightDreamManager {
|
||||
@Inject
|
||||
public LowLightDreamManager(
|
||||
DreamManager dreamManager,
|
||||
LowLightTransitionCoordinator lowLightTransitionCoordinator,
|
||||
@Named(LOW_LIGHT_DREAM_COMPONENT) @Nullable ComponentName lowLightDreamComponent) {
|
||||
mDreamManager = dreamManager;
|
||||
mLowLightTransitionCoordinator = lowLightTransitionCoordinator;
|
||||
mLowLightDreamComponent = lowLightDreamComponent;
|
||||
}
|
||||
|
||||
@@ -111,7 +114,9 @@ public final class LowLightDreamManager {
|
||||
|
||||
mAmbientLightMode = ambientLightMode;
|
||||
|
||||
mDreamManager.setSystemDreamComponent(mAmbientLightMode == AMBIENT_LIGHT_MODE_LOW_LIGHT
|
||||
? mLowLightDreamComponent : null);
|
||||
boolean shouldEnterLowLight = mAmbientLightMode == AMBIENT_LIGHT_MODE_LOW_LIGHT;
|
||||
mLowLightTransitionCoordinator.notifyBeforeLowLightTransition(shouldEnterLowLight,
|
||||
() -> mDreamManager.setSystemDreamComponent(
|
||||
shouldEnterLowLight ? mLowLightDreamComponent : null));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.dream.lowlight;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.animation.AnimatorListenerAdapter;
|
||||
import android.annotation.Nullable;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
/**
|
||||
* Helper class that allows listening and running animations before entering or exiting low light.
|
||||
*/
|
||||
@Singleton
|
||||
public class LowLightTransitionCoordinator {
|
||||
/**
|
||||
* Listener that is notified before low light entry.
|
||||
*/
|
||||
public interface LowLightEnterListener {
|
||||
/**
|
||||
* Callback that is notified before the device enters low light.
|
||||
*
|
||||
* @return an optional animator that will be waited upon before entering low light.
|
||||
*/
|
||||
Animator onBeforeEnterLowLight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Listener that is notified before low light exit.
|
||||
*/
|
||||
public interface LowLightExitListener {
|
||||
/**
|
||||
* Callback that is notified before the device exits low light.
|
||||
*
|
||||
* @return an optional animator that will be waited upon before exiting low light.
|
||||
*/
|
||||
Animator onBeforeExitLowLight();
|
||||
}
|
||||
|
||||
private LowLightEnterListener mLowLightEnterListener;
|
||||
private LowLightExitListener mLowLightExitListener;
|
||||
|
||||
@Inject
|
||||
public LowLightTransitionCoordinator() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the listener for the low light enter event.
|
||||
*
|
||||
* Only one listener can be set at a time. This method will overwrite any previously set
|
||||
* listener. Null can be used to unset the listener.
|
||||
*/
|
||||
public void setLowLightEnterListener(@Nullable LowLightEnterListener lowLightEnterListener) {
|
||||
mLowLightEnterListener = lowLightEnterListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the listener for the low light exit event.
|
||||
*
|
||||
* Only one listener can be set at a time. This method will overwrite any previously set
|
||||
* listener. Null can be used to unset the listener.
|
||||
*/
|
||||
public void setLowLightExitListener(@Nullable LowLightExitListener lowLightExitListener) {
|
||||
mLowLightExitListener = lowLightExitListener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Notifies listeners that the device is about to enter or exit low light.
|
||||
*
|
||||
* @param entering true if listeners should be notified before entering low light, false if this
|
||||
* is notifying before exiting.
|
||||
* @param callback callback that will be run after listeners complete.
|
||||
*/
|
||||
void notifyBeforeLowLightTransition(boolean entering, Runnable callback) {
|
||||
Animator animator = null;
|
||||
|
||||
if (entering && mLowLightEnterListener != null) {
|
||||
animator = mLowLightEnterListener.onBeforeEnterLowLight();
|
||||
} else if (!entering && mLowLightExitListener != null) {
|
||||
animator = mLowLightExitListener.onBeforeExitLowLight();
|
||||
}
|
||||
|
||||
// If the listener returned an animator to indicate it was running an animation, run the
|
||||
// callback after the animation completes, otherwise call the callback directly.
|
||||
if (animator != null) {
|
||||
animator.addListener(new AnimatorListenerAdapter() {
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animator) {
|
||||
callback.run();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
callback.run();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,10 @@ import static com.android.dream.lowlight.LowLightDreamManager.AMBIENT_LIGHT_MODE
|
||||
import static com.android.dream.lowlight.LowLightDreamManager.AMBIENT_LIGHT_MODE_UNKNOWN;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyBoolean;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
|
||||
@@ -43,45 +46,53 @@ public class LowLightDreamManagerTest {
|
||||
@Mock
|
||||
private DreamManager mDreamManager;
|
||||
|
||||
@Mock
|
||||
private LowLightTransitionCoordinator mTransitionCoordinator;
|
||||
|
||||
@Mock
|
||||
private ComponentName mDreamComponent;
|
||||
|
||||
LowLightDreamManager mLowLightDreamManager;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
|
||||
// Automatically run any provided Runnable to mTransitionCoordinator to simplify testing.
|
||||
doAnswer(invocation -> {
|
||||
((Runnable) invocation.getArgument(1)).run();
|
||||
return null;
|
||||
}).when(mTransitionCoordinator).notifyBeforeLowLightTransition(anyBoolean(),
|
||||
any(Runnable.class));
|
||||
|
||||
mLowLightDreamManager = new LowLightDreamManager(mDreamManager, mTransitionCoordinator,
|
||||
mDreamComponent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAmbientLightMode_lowLight_setSystemDream() {
|
||||
final LowLightDreamManager lowLightDreamManager = new LowLightDreamManager(mDreamManager,
|
||||
mDreamComponent);
|
||||
|
||||
lowLightDreamManager.setAmbientLightMode(AMBIENT_LIGHT_MODE_LOW_LIGHT);
|
||||
mLowLightDreamManager.setAmbientLightMode(AMBIENT_LIGHT_MODE_LOW_LIGHT);
|
||||
|
||||
verify(mTransitionCoordinator).notifyBeforeLowLightTransition(eq(true), any());
|
||||
verify(mDreamManager).setSystemDreamComponent(mDreamComponent);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAmbientLightMode_regularLight_clearSystemDream() {
|
||||
final LowLightDreamManager lowLightDreamManager = new LowLightDreamManager(mDreamManager,
|
||||
mDreamComponent);
|
||||
|
||||
lowLightDreamManager.setAmbientLightMode(AMBIENT_LIGHT_MODE_REGULAR);
|
||||
mLowLightDreamManager.setAmbientLightMode(AMBIENT_LIGHT_MODE_REGULAR);
|
||||
|
||||
verify(mTransitionCoordinator).notifyBeforeLowLightTransition(eq(false), any());
|
||||
verify(mDreamManager).setSystemDreamComponent(null);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void setAmbientLightMode_defaultUnknownMode_clearSystemDream() {
|
||||
final LowLightDreamManager lowLightDreamManager = new LowLightDreamManager(mDreamManager,
|
||||
mDreamComponent);
|
||||
|
||||
// Set to low light first.
|
||||
lowLightDreamManager.setAmbientLightMode(AMBIENT_LIGHT_MODE_LOW_LIGHT);
|
||||
mLowLightDreamManager.setAmbientLightMode(AMBIENT_LIGHT_MODE_LOW_LIGHT);
|
||||
clearInvocations(mDreamManager);
|
||||
|
||||
// Return to default unknown mode.
|
||||
lowLightDreamManager.setAmbientLightMode(AMBIENT_LIGHT_MODE_UNKNOWN);
|
||||
mLowLightDreamManager.setAmbientLightMode(AMBIENT_LIGHT_MODE_UNKNOWN);
|
||||
|
||||
verify(mDreamManager).setSystemDreamComponent(null);
|
||||
}
|
||||
@@ -89,7 +100,7 @@ public class LowLightDreamManagerTest {
|
||||
@Test
|
||||
public void setAmbientLightMode_dreamComponentNotSet_doNothing() {
|
||||
final LowLightDreamManager lowLightDreamManager = new LowLightDreamManager(mDreamManager,
|
||||
null /*dream component*/);
|
||||
mTransitionCoordinator, null /*dream component*/);
|
||||
|
||||
lowLightDreamManager.setAmbientLightMode(AMBIENT_LIGHT_MODE_LOW_LIGHT);
|
||||
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.dream.lowlight;
|
||||
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyZeroInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.testing.AndroidTestingRunner;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
@SmallTest
|
||||
@RunWith(AndroidTestingRunner.class)
|
||||
public class LowLightTransitionCoordinatorTest {
|
||||
@Mock
|
||||
private LowLightTransitionCoordinator.LowLightEnterListener mEnterListener;
|
||||
|
||||
@Mock
|
||||
private LowLightTransitionCoordinator.LowLightExitListener mExitListener;
|
||||
|
||||
@Mock
|
||||
private Animator mAnimator;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<Animator.AnimatorListener> mAnimatorListenerCaptor;
|
||||
|
||||
@Mock
|
||||
private Runnable mRunnable;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onEnterCalledOnListeners() {
|
||||
LowLightTransitionCoordinator coordinator = new LowLightTransitionCoordinator();
|
||||
|
||||
coordinator.setLowLightEnterListener(mEnterListener);
|
||||
|
||||
coordinator.notifyBeforeLowLightTransition(true, mRunnable);
|
||||
|
||||
verify(mEnterListener).onBeforeEnterLowLight();
|
||||
verify(mRunnable).run();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onExitCalledOnListeners() {
|
||||
LowLightTransitionCoordinator coordinator = new LowLightTransitionCoordinator();
|
||||
|
||||
coordinator.setLowLightExitListener(mExitListener);
|
||||
|
||||
coordinator.notifyBeforeLowLightTransition(false, mRunnable);
|
||||
|
||||
verify(mExitListener).onBeforeExitLowLight();
|
||||
verify(mRunnable).run();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void listenerNotCalledAfterRemoval() {
|
||||
LowLightTransitionCoordinator coordinator = new LowLightTransitionCoordinator();
|
||||
|
||||
coordinator.setLowLightEnterListener(mEnterListener);
|
||||
coordinator.setLowLightEnterListener(null);
|
||||
|
||||
coordinator.notifyBeforeLowLightTransition(true, mRunnable);
|
||||
|
||||
verifyZeroInteractions(mEnterListener);
|
||||
verify(mRunnable).run();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void runnableCalledAfterAnimationEnds() {
|
||||
when(mEnterListener.onBeforeEnterLowLight()).thenReturn(mAnimator);
|
||||
|
||||
LowLightTransitionCoordinator coordinator = new LowLightTransitionCoordinator();
|
||||
coordinator.setLowLightEnterListener(mEnterListener);
|
||||
|
||||
coordinator.notifyBeforeLowLightTransition(true, mRunnable);
|
||||
|
||||
// Animator listener is added and the runnable is not run yet.
|
||||
verify(mAnimator).addListener(mAnimatorListenerCaptor.capture());
|
||||
verifyZeroInteractions(mRunnable);
|
||||
|
||||
// Runnable is run once the animation ends.
|
||||
mAnimatorListenerCaptor.getValue().onAnimationEnd(null);
|
||||
verify(mRunnable).run();
|
||||
}
|
||||
}
|
||||
@@ -774,7 +774,7 @@
|
||||
<!-- Duration in milliseconds of the dream in complications fade-in animation. -->
|
||||
<integer name="config_dreamOverlayInComplicationsDurationMs">250</integer>
|
||||
<!-- Duration in milliseconds of the y-translation animation when entering a dream -->
|
||||
<integer name="config_dreamOverlayInTranslationYDurationMs">917</integer>
|
||||
<integer name="config_dreamOverlayInTranslationYDurationMs">1167</integer>
|
||||
|
||||
<!-- Delay in milliseconds before switching to the dock user and dreaming if a secondary user is
|
||||
active when the device is locked and docked. 0 indicates disabled. Default is 1 minute. -->
|
||||
|
||||
@@ -174,6 +174,71 @@ constructor(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts the dream content and dream overlay exit animations.
|
||||
*
|
||||
* This should only be used when the low light dream is entering, animations to/from other SysUI
|
||||
* views is controlled by `transitionViewModel`.
|
||||
*/
|
||||
// TODO(b/256916668): integrate with the keyguard transition model once dream surfaces work is
|
||||
// done.
|
||||
@JvmOverloads
|
||||
fun startExitAnimations(animatorBuilder: () -> AnimatorSet = { AnimatorSet() }): Animator {
|
||||
cancelAnimations()
|
||||
|
||||
mAnimator =
|
||||
animatorBuilder().apply {
|
||||
playTogether(
|
||||
translationYAnimator(
|
||||
from = 0f,
|
||||
to = -mDreamInTranslationYDistance.toFloat(),
|
||||
durationMs = mDreamInTranslationYDurationMs,
|
||||
delayMs = 0,
|
||||
interpolator = Interpolators.EMPHASIZED
|
||||
),
|
||||
alphaAnimator(
|
||||
from =
|
||||
mCurrentAlphaAtPosition.getOrDefault(
|
||||
key = POSITION_BOTTOM,
|
||||
defaultValue = 1f
|
||||
),
|
||||
to = 0f,
|
||||
durationMs = mDreamInComplicationsAnimDurationMs,
|
||||
delayMs = 0,
|
||||
positions = POSITION_BOTTOM
|
||||
)
|
||||
.apply {
|
||||
doOnEnd {
|
||||
// The logical end of the animation is once the alpha and blur
|
||||
// animations finish, end the animation so that any listeners are
|
||||
// notified. The Y translation animation is much longer than all of
|
||||
// the other animations due to how the spec is defined, but is not
|
||||
// expected to run to completion.
|
||||
mAnimator?.end()
|
||||
}
|
||||
},
|
||||
alphaAnimator(
|
||||
from =
|
||||
mCurrentAlphaAtPosition.getOrDefault(
|
||||
key = POSITION_TOP,
|
||||
defaultValue = 1f
|
||||
),
|
||||
to = 0f,
|
||||
durationMs = mDreamInComplicationsAnimDurationMs,
|
||||
delayMs = 0,
|
||||
positions = POSITION_TOP
|
||||
)
|
||||
)
|
||||
doOnEnd {
|
||||
mAnimator = null
|
||||
mOverlayStateController.setExitAnimationsRunning(false)
|
||||
}
|
||||
start()
|
||||
}
|
||||
mOverlayStateController.setExitAnimationsRunning(true)
|
||||
return mAnimator as AnimatorSet
|
||||
}
|
||||
|
||||
/** Starts the dream content and dream overlay exit animations. */
|
||||
fun wakeUp(doneCallback: Runnable, executor: DelayableExecutor) {
|
||||
cancelAnimations()
|
||||
|
||||
@@ -23,6 +23,7 @@ import static com.android.systemui.doze.util.BurnInHelperKt.getBurnInOffset;
|
||||
import static com.android.systemui.dreams.complication.ComplicationLayoutParams.POSITION_BOTTOM;
|
||||
import static com.android.systemui.dreams.complication.ComplicationLayoutParams.POSITION_TOP;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.content.res.Resources;
|
||||
import android.os.Handler;
|
||||
import android.util.MathUtils;
|
||||
@@ -31,6 +32,7 @@ import android.view.ViewGroup;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.android.dream.lowlight.LowLightTransitionCoordinator;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.animation.Interpolators;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
@@ -54,11 +56,14 @@ import javax.inject.Named;
|
||||
* View controller for {@link DreamOverlayContainerView}.
|
||||
*/
|
||||
@DreamOverlayComponent.DreamOverlayScope
|
||||
public class DreamOverlayContainerViewController extends ViewController<DreamOverlayContainerView> {
|
||||
public class DreamOverlayContainerViewController extends
|
||||
ViewController<DreamOverlayContainerView> implements
|
||||
LowLightTransitionCoordinator.LowLightEnterListener {
|
||||
private final DreamOverlayStatusBarViewController mStatusBarViewController;
|
||||
private final BlurUtils mBlurUtils;
|
||||
private final DreamOverlayAnimationsController mDreamOverlayAnimationsController;
|
||||
private final DreamOverlayStateController mStateController;
|
||||
private final LowLightTransitionCoordinator mLowLightTransitionCoordinator;
|
||||
|
||||
private final ComplicationHostViewController mComplicationHostViewController;
|
||||
|
||||
@@ -164,6 +169,7 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve
|
||||
ComplicationHostViewController complicationHostViewController,
|
||||
@Named(DreamOverlayModule.DREAM_OVERLAY_CONTENT_VIEW) ViewGroup contentView,
|
||||
DreamOverlayStatusBarViewController statusBarViewController,
|
||||
LowLightTransitionCoordinator lowLightTransitionCoordinator,
|
||||
BlurUtils blurUtils,
|
||||
@Main Handler handler,
|
||||
@Main Resources resources,
|
||||
@@ -181,6 +187,7 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve
|
||||
mBlurUtils = blurUtils;
|
||||
mDreamOverlayAnimationsController = animationsController;
|
||||
mStateController = stateController;
|
||||
mLowLightTransitionCoordinator = lowLightTransitionCoordinator;
|
||||
|
||||
mBouncerlessScrimController = bouncerlessScrimController;
|
||||
mBouncerlessScrimController.addCallback(mBouncerlessExpansionCallback);
|
||||
@@ -207,6 +214,7 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve
|
||||
mStatusBarViewController.init();
|
||||
mComplicationHostViewController.init();
|
||||
mDreamOverlayAnimationsController.init(mView);
|
||||
mLowLightTransitionCoordinator.setLowLightEnterListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -305,4 +313,12 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve
|
||||
|
||||
mDreamOverlayAnimationsController.wakeUp(onAnimationEnd, callbackExecutor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Animator onBeforeEnterLowLight() {
|
||||
// Return the animator so that the transition coordinator waits for the overlay exit
|
||||
// animations to finish before entering low light, as otherwise the default DreamActivity
|
||||
// animation plays immediately and there's no time for this animation to play.
|
||||
return mDreamOverlayAnimationsController.startExitAnimations();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.android.systemui.dreams
|
||||
|
||||
import android.animation.Animator
|
||||
import android.animation.AnimatorSet
|
||||
import android.animation.ValueAnimator
|
||||
import android.testing.AndroidTestingRunner
|
||||
@@ -11,6 +12,7 @@ import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransition
|
||||
import com.android.systemui.statusbar.BlurUtils
|
||||
import com.android.systemui.statusbar.policy.ConfigurationController
|
||||
import com.android.systemui.util.concurrency.DelayableExecutor
|
||||
import com.android.systemui.util.mockito.argumentCaptor
|
||||
import com.android.systemui.util.mockito.mock
|
||||
import com.android.systemui.util.mockito.whenever
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -73,6 +75,19 @@ class DreamOverlayAnimationsControllerTest : SysuiTestCase() {
|
||||
runBlocking(Dispatchers.Main.immediate) { controller.init(mockView) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testExitAnimationUpdatesState() {
|
||||
controller.startExitAnimations(animatorBuilder = { mockAnimator })
|
||||
|
||||
verify(stateController).setExitAnimationsRunning(true)
|
||||
|
||||
val captor = argumentCaptor<Animator.AnimatorListener>()
|
||||
verify(mockAnimator).addListener(captor.capture())
|
||||
|
||||
captor.value.onAnimationEnd(mockAnimator)
|
||||
verify(stateController).setExitAnimationsRunning(false)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testWakeUpCallsExecutor() {
|
||||
val mockExecutor: DelayableExecutor = mock()
|
||||
|
||||
@@ -34,6 +34,7 @@ import android.view.ViewTreeObserver;
|
||||
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.dream.lowlight.LowLightTransitionCoordinator;
|
||||
import com.android.keyguard.BouncerPanelExpansionCalculator;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.dreams.complication.ComplicationHostViewController;
|
||||
@@ -65,6 +66,9 @@ public class DreamOverlayContainerViewControllerTest extends SysuiTestCase {
|
||||
@Mock
|
||||
DreamOverlayStatusBarViewController mDreamOverlayStatusBarViewController;
|
||||
|
||||
@Mock
|
||||
LowLightTransitionCoordinator mLowLightTransitionCoordinator;
|
||||
|
||||
@Mock
|
||||
DreamOverlayContainerView mDreamOverlayContainerView;
|
||||
|
||||
@@ -110,6 +114,7 @@ public class DreamOverlayContainerViewControllerTest extends SysuiTestCase {
|
||||
mComplicationHostViewController,
|
||||
mDreamOverlayContentView,
|
||||
mDreamOverlayStatusBarViewController,
|
||||
mLowLightTransitionCoordinator,
|
||||
mBlurUtils,
|
||||
mHandler,
|
||||
mResources,
|
||||
@@ -234,6 +239,13 @@ public class DreamOverlayContainerViewControllerTest extends SysuiTestCase {
|
||||
verify(mAnimationsController).startEntryAnimations(true);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testStartsExitAnimationsBeforeEnteringLowLight() {
|
||||
mController.onBeforeEnterLowLight();
|
||||
|
||||
verify(mAnimationsController).startExitAnimations();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCancelDreamEntryAnimationsOnDetached() {
|
||||
mController.onViewAttached();
|
||||
|
||||
Reference in New Issue
Block a user