Skip dream overlay animations when exiting low light

The dream overlay currently does not animate when entering low light
mode, but does animate when exiting it. This CL skips the animations
when leaving low light and going back to the user dream for consistency.

Bug: 260638159
Test: atest DreamOverlayStateControllerTest, atest DreamOverlayContainerViewControllerTest
      manually verified animations on device

Change-Id: Ie097eaeef803cd5d39fa3c8206a2263ca22d5119
This commit is contained in:
William Xiao
2023-01-25 13:14:03 -08:00
parent 87f4c66c0a
commit e412b167ea
5 changed files with 92 additions and 0 deletions

View File

@@ -182,6 +182,18 @@ constructor(
}
}
/**
* Ends the dream content and dream overlay animations, if they're currently running.
* @see [AnimatorSet.end]
*/
fun endAnimations() {
mAnimator =
mAnimator?.let {
it.end()
null
}
}
private fun blurAnimator(
view: View,
fromBlurRadius: Float,

View File

@@ -127,6 +127,23 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve
}
};
/**
* If true, overlay entry animations should be skipped once.
*
* This is turned on when exiting low light and should be turned off once the entry animations
* are skipped once.
*/
private boolean mSkipEntryAnimations;
private final DreamOverlayStateController.Callback
mDreamOverlayStateCallback =
new DreamOverlayStateController.Callback() {
@Override
public void onExitLowLight() {
mSkipEntryAnimations = true;
}
};
@Inject
public DreamOverlayContainerViewController(
DreamOverlayContainerView containerView,
@@ -170,6 +187,7 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve
@Override
protected void onInit() {
mStateController.addCallback(mDreamOverlayStateCallback);
mStatusBarViewController.init();
mComplicationHostViewController.init();
mDreamOverlayAnimationsController.init(mView);
@@ -188,6 +206,13 @@ public class DreamOverlayContainerViewController extends ViewController<DreamOve
// Start dream entry animations. Skip animations for low light clock.
if (!mStateController.isLowLightActive()) {
mDreamOverlayAnimationsController.startEntryAnimations();
if (mSkipEntryAnimations) {
// If we're transitioning from the low light dream back to the user dream, skip the
// overlay animations and show immediately.
mDreamOverlayAnimationsController.endAnimations();
mSkipEntryAnimations = false;
}
}
}

View File

@@ -83,6 +83,12 @@ public class DreamOverlayStateController implements
*/
default void onAvailableComplicationTypesChanged() {
}
/**
* Called when the low light dream is exiting and transitioning back to the user dream.
*/
default void onExitLowLight() {
}
}
private final Executor mExecutor;
@@ -278,6 +284,10 @@ public class DreamOverlayStateController implements
* @param active {@code true} if low light mode is active, {@code false} otherwise.
*/
public void setLowLightActive(boolean active) {
if (isLowLightActive() && !active) {
// Notify that we're exiting low light only on the transition from active to not active.
mCallbacks.forEach(Callback::onExitLowLight);
}
modifyState(active ? OP_SET_STATE : OP_CLEAR_STATE, STATE_LOW_LIGHT_ACTIVE);
}

View File

@@ -216,6 +216,27 @@ public class DreamOverlayContainerViewControllerTest extends SysuiTestCase {
verify(mAnimationsController, never()).startEntryAnimations();
}
@Test
public void testSkipEntryAnimationsWhenExitingLowLight() {
ArgumentCaptor<DreamOverlayStateController.Callback> callbackCaptor =
ArgumentCaptor.forClass(DreamOverlayStateController.Callback.class);
when(mStateController.isLowLightActive()).thenReturn(false);
// Call onInit so that the callback is added.
mController.onInit();
verify(mStateController).addCallback(callbackCaptor.capture());
// Send the signal that low light is exiting
callbackCaptor.getValue().onExitLowLight();
// View is attached to trigger animations.
mController.onViewAttached();
// Entry animations should be started then immediately ended to skip to the end.
verify(mAnimationsController).startEntryAnimations();
verify(mAnimationsController).endAnimations();
}
@Test
public void testCancelDreamEntryAnimationsOnDetached() {
mController.onViewAttached();

View File

@@ -250,6 +250,30 @@ public class DreamOverlayStateControllerTest extends SysuiTestCase {
assertThat(stateController.isLowLightActive()).isTrue();
}
@Test
public void testNotifyLowLightExit() {
final DreamOverlayStateController stateController =
new DreamOverlayStateController(mExecutor, true);
stateController.addCallback(mCallback);
mExecutor.runAllReady();
assertThat(stateController.isLowLightActive()).isFalse();
// Turn low light on then off to trigger the exiting callback.
stateController.setLowLightActive(true);
stateController.setLowLightActive(false);
// Callback was only called once, when
mExecutor.runAllReady();
verify(mCallback, times(1)).onExitLowLight();
assertThat(stateController.isLowLightActive()).isFalse();
// Set with false again, which should not cause the callback to trigger again.
stateController.setLowLightActive(false);
mExecutor.runAllReady();
verify(mCallback, times(1)).onExitLowLight();
}
@Test
public void testNotifyEntryAnimationsFinishedChanged() {
final DreamOverlayStateController stateController =