From 9b898b8f1a244ee56e7e55a2000fb8c89b020250 Mon Sep 17 00:00:00 2001 From: Matt Pietal Date: Fri, 16 Dec 2022 15:25:51 +0000 Subject: [PATCH] [DO NOT MERGE] DREAMING->LOCKSCREEN, lockscreen updates This will address this transition, as well as handle all general unocclusion, by listening to the KeyguardTransitionRepository for events rather than attempting to coordinate individual views across many controllers. To enable: adb shell cmd statusbar flag 223 true Test: atest DreamingToLockscreenTransitionViewModelTest KeyguardStatusViewTest KeyguardStatusViewControllerTest NotificationPanelViewControllerTest Bug: 260631205 Change-Id: I70d5b68a8f9c6b2fa738445d46435f3f09d1f68d --- packages/SystemUI/res/values/dimens.xml | 3 + .../android/keyguard/KeyguardStatusView.java | 7 +- .../KeyguardStatusViewController.java | 9 +- .../keyguard/KeyguardVisibilityHelper.java | 11 ++- .../src/com/android/systemui/flags/Flags.kt | 13 ++- .../keyguard/KeyguardViewMediator.java | 4 +- .../DreamingTransitionInteractor.kt | 1 - ...DreamingToLockscreenTransitionViewModel.kt | 14 +-- .../NotificationPanelViewController.java | 83 ++++++++++++++++- ...tificationStackScrollLayoutController.java | 5 ++ .../statusbar/phone/ScrimController.java | 5 -- .../phone/StatusBarKeyguardViewManager.java | 10 ++- .../KeyguardStatusViewControllerTest.java | 8 +- .../keyguard/KeyguardStatusViewTest.kt | 22 +++-- ...mingToLockscreenTransitionViewModelTest.kt | 90 +++++++++++++++++-- .../NotificationPanelViewControllerTest.java | 6 ++ 16 files changed, 244 insertions(+), 47 deletions(-) diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 87d2c51c73257..f37d22146b251 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -1272,6 +1272,9 @@ translate into their final position. --> @dimen/lockscreen_shade_media_transition_distance + + 40dp + 0dp diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java index 8b9823be65fd5..b8e196fb8787b 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusView.java @@ -16,6 +16,8 @@ package com.android.keyguard; +import static java.util.Collections.emptySet; + import android.content.Context; import android.os.Trace; import android.util.AttributeSet; @@ -88,8 +90,9 @@ public class KeyguardStatusView extends GridLayout { } /** Sets a translationY value on every child view except for the media view. */ - public void setChildrenTranslationYExcludingMediaView(float translationY) { - setChildrenTranslationYExcluding(translationY, Set.of(mMediaHostContainer)); + public void setChildrenTranslationY(float translationY, boolean excludeMedia) { + setChildrenTranslationYExcluding(translationY, + excludeMedia ? Set.of(mMediaHostContainer) : emptySet()); } /** Sets a translationY value on every view except for the views in the provided set. */ diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java index 784974778af57..aec30632c41e6 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java @@ -20,6 +20,8 @@ import android.graphics.Rect; import android.util.Slog; import com.android.keyguard.KeyguardClockSwitch.ClockSize; +import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.flags.Flags; import com.android.systemui.plugins.ClockAnimations; import com.android.systemui.statusbar.notification.AnimatableProperty; import com.android.systemui.statusbar.notification.PropertyAnimator; @@ -59,6 +61,7 @@ public class KeyguardStatusViewController extends ViewController = flowForAnimation(DREAM_OVERLAY_ALPHA).map { 1f - it } - /** Dream background alpha - fade out */ - val dreamBackgroundAlpha: Flow = flowForAnimation(DREAM_BACKGROUND_ALPHA).map { 1f - it } - /** Lockscreen views y-translation */ fun lockscreenTranslationY(translatePx: Int): Flow { - return flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { it * translatePx } + return flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { value -> + -translatePx + (EMPHASIZED_DECELERATE.getInterpolation(value) * translatePx) + } } /** Lockscreen views alpha */ @@ -68,10 +68,12 @@ constructor( companion object { /* Length of time before ending the dream activity, in order to start unoccluding */ val DREAM_ANIMATION_DURATION = 250.milliseconds + @JvmField + val LOCKSCREEN_ANIMATION_DURATION_MS = + (TO_LOCKSCREEN_DURATION - DREAM_ANIMATION_DURATION).inWholeMilliseconds - val DREAM_OVERLAY_TRANSLATION_Y = AnimationParams(duration = 500.milliseconds) + val DREAM_OVERLAY_TRANSLATION_Y = AnimationParams(duration = 600.milliseconds) val DREAM_OVERLAY_ALPHA = AnimationParams(duration = 250.milliseconds) - val DREAM_BACKGROUND_ALPHA = AnimationParams(duration = 250.milliseconds) val LOCKSCREEN_TRANSLATION_Y = AnimationParams(duration = TO_LOCKSCREEN_DURATION) val LOCKSCREEN_ALPHA = AnimationParams(startTime = 233.milliseconds, duration = 250.milliseconds) diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index fcdde799267ba..8054f27029ae6 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -44,6 +44,7 @@ import static com.android.systemui.statusbar.StatusBarState.SHADE_LOCKED; import static com.android.systemui.statusbar.VibratorHelper.TOUCH_VIBRATION_ATTRIBUTES; import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_FOLD_TO_AOD; import static com.android.systemui.util.DumpUtilsKt.asIndenting; +import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow; import static java.lang.Float.isNaN; @@ -138,6 +139,10 @@ import com.android.systemui.fragments.FragmentHostManager.FragmentListener; import com.android.systemui.fragments.FragmentService; import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor; +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; +import com.android.systemui.keyguard.shared.model.TransitionState; +import com.android.systemui.keyguard.shared.model.TransitionStep; +import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel; import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel; import com.android.systemui.media.controls.pipeline.MediaDataManager; import com.android.systemui.media.controls.ui.KeyguardMediaController; @@ -677,6 +682,12 @@ public final class NotificationPanelViewController implements Dumpable { private boolean mGestureWaitForTouchSlop; private boolean mIgnoreXTouchSlop; private boolean mExpandLatencyTracking; + private DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel; + + private KeyguardTransitionInteractor mKeyguardTransitionInteractor; + private boolean mIsDreamToLockscreenTransitionRunning = false; + private int mDreamingToLockscreenTransitionTranslationY; + private boolean mUnocclusionTransitionFlagEnabled = false; private final Runnable mFlingCollapseRunnable = () -> fling(0, false /* expand */, mNextCollapseSpeedUpFactor, false /* expandBecauseOfFalsing */); @@ -692,6 +703,12 @@ public final class NotificationPanelViewController implements Dumpable { } }; + private final Consumer mDreamingToLockscreenTransition = + (TransitionStep step) -> { + mIsDreamToLockscreenTransitionRunning = + step.getTransitionState() == TransitionState.RUNNING; + }; + @Inject public NotificationPanelViewController(NotificationPanelView view, @Main Handler handler, @@ -760,6 +777,8 @@ public final class NotificationPanelViewController implements Dumpable { SystemClock systemClock, KeyguardBottomAreaViewModel keyguardBottomAreaViewModel, KeyguardBottomAreaInteractor keyguardBottomAreaInteractor, + DreamingToLockscreenTransitionViewModel dreamingToLockscreenTransitionViewModel, + KeyguardTransitionInteractor keyguardTransitionInteractor, DumpManager dumpManager) { keyguardStateController.addCallback(new KeyguardStateController.Callback() { @Override @@ -775,6 +794,8 @@ public final class NotificationPanelViewController implements Dumpable { mShadeLog = shadeLogger; mShadeHeightLogger = shadeHeightLogger; mGutsManager = gutsManager; + mDreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel; + mKeyguardTransitionInteractor = keyguardTransitionInteractor; mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { @Override public void onViewAttachedToWindow(View v) { @@ -920,6 +941,8 @@ public final class NotificationPanelViewController implements Dumpable { mNotificationPanelUnfoldAnimationController = unfoldComponent.map( SysUIUnfoldComponent::getNotificationPanelUnfoldAnimationController); + mUnocclusionTransitionFlagEnabled = featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION); + mQsFrameTranslateController = qsFrameTranslateController; updateUserSwitcherFlags(); mKeyguardBottomAreaViewModel = keyguardBottomAreaViewModel; @@ -1072,6 +1095,18 @@ public final class NotificationPanelViewController implements Dumpable { mKeyguardUnfoldTransition.ifPresent(u -> u.setup(mView)); mNotificationPanelUnfoldAnimationController.ifPresent(controller -> controller.setup(mNotificationContainerParent)); + + if (mUnocclusionTransitionFlagEnabled) { + collectFlow(mView, mDreamingToLockscreenTransitionViewModel.getLockscreenAlpha(), + dreamingToLockscreenTransitionAlpha(mNotificationStackScrollLayoutController)); + + collectFlow(mView, mDreamingToLockscreenTransitionViewModel.lockscreenTranslationY( + mDreamingToLockscreenTransitionTranslationY), + dreamingToLockscreenTransitionY(mNotificationStackScrollLayoutController)); + + collectFlow(mView, mKeyguardTransitionInteractor.getDreamingToLockscreenTransition(), + mDreamingToLockscreenTransition); + } } @VisibleForTesting @@ -1106,6 +1141,8 @@ public final class NotificationPanelViewController implements Dumpable { mUdfpsMaxYBurnInOffset = mResources.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y); mSplitShadeScrimTransitionDistance = mResources.getDimensionPixelSize( R.dimen.split_shade_scrim_transition_distance); + mDreamingToLockscreenTransitionTranslationY = mResources.getDimensionPixelSize( + R.dimen.dreaming_to_lockscreen_transition_lockscreen_translation_y); } private void updateViewControllers(KeyguardStatusView keyguardStatusView, @@ -1769,10 +1806,14 @@ public final class NotificationPanelViewController implements Dumpable { } private void updateClock() { + if (mIsDreamToLockscreenTransitionRunning) { + return; + } float alpha = mClockPositionResult.clockAlpha * mKeyguardOnlyContentAlpha; mKeyguardStatusViewController.setAlpha(alpha); mKeyguardStatusViewController - .setTranslationYExcludingMedia(mKeyguardOnlyTransitionTranslationY); + .setTranslationY(mKeyguardOnlyTransitionTranslationY, /* excludeMedia= */true); + if (mKeyguardQsUserSwitchController != null) { mKeyguardQsUserSwitchController.setAlpha(alpha); } @@ -2656,7 +2697,9 @@ public final class NotificationPanelViewController implements Dumpable { } else if (statusBarState == KEYGUARD || statusBarState == StatusBarState.SHADE_LOCKED) { mKeyguardBottomArea.setVisibility(View.VISIBLE); - mKeyguardBottomArea.setAlpha(1f); + if (!mIsDreamToLockscreenTransitionRunning) { + mKeyguardBottomArea.setAlpha(1f); + } } else { mKeyguardBottomArea.setVisibility(View.GONE); } @@ -3523,6 +3566,9 @@ public final class NotificationPanelViewController implements Dumpable { } private void updateNotificationTranslucency() { + if (mIsDreamToLockscreenTransitionRunning) { + return; + } float alpha = 1f; if (mClosingWithAlphaFadeOut && !mExpandingFromHeadsUp && !mHeadsUpManager.hasPinnedHeadsUp()) { @@ -3578,6 +3624,9 @@ public final class NotificationPanelViewController implements Dumpable { } private void updateKeyguardBottomAreaAlpha() { + if (mIsDreamToLockscreenTransitionRunning) { + return; + } // There are two possible panel expansion behaviors: // • User dragging up to unlock: we want to fade out as quick as possible // (ALPHA_EXPANSION_THRESHOLD) to avoid seeing the bouncer over the bottom area. @@ -3610,7 +3659,9 @@ public final class NotificationPanelViewController implements Dumpable { } private void onExpandingFinished() { - mScrimController.onExpandingFinished(); + if (!mUnocclusionTransitionFlagEnabled) { + mScrimController.onExpandingFinished(); + } mNotificationStackScrollLayoutController.onExpansionStopped(); mHeadsUpManager.onExpandingFinished(); mConversationNotificationManager.onNotificationPanelExpandStateChanged(isFullyCollapsed()); @@ -5805,6 +5856,32 @@ public final class NotificationPanelViewController implements Dumpable { mCurrentPanelState = state; } + private Consumer dreamingToLockscreenTransitionAlpha( + NotificationStackScrollLayoutController stackScroller) { + return (Float alpha) -> { + mKeyguardStatusViewController.setAlpha(alpha); + stackScroller.setAlpha(alpha); + + mKeyguardBottomAreaInteractor.setAlpha(alpha); + mLockIconViewController.setAlpha(alpha); + + if (mKeyguardQsUserSwitchController != null) { + mKeyguardQsUserSwitchController.setAlpha(alpha); + } + if (mKeyguardUserSwitcherController != null) { + mKeyguardUserSwitcherController.setAlpha(alpha); + } + }; + } + + private Consumer dreamingToLockscreenTransitionY( + NotificationStackScrollLayoutController stackScroller) { + return (Float translationY) -> { + mKeyguardStatusViewController.setTranslationY(translationY, /* excludeMedia= */false); + stackScroller.setTranslationY(translationY); + }; + } + @VisibleForTesting StatusBarStateController getStatusBarStateController() { return mStatusBarStateController; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java index 4bcc0b6923a11..c2c38a7b355bb 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java @@ -916,6 +916,11 @@ public class NotificationStackScrollLayoutController { return mView.getTranslationX(); } + /** Set view y-translation */ + public void setTranslationY(float translationY) { + mView.setTranslationY(translationY); + } + public int indexOfChild(View view) { return mView.indexOfChild(view); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index d500f999b5e2b..ee8b86160f515 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -232,7 +232,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump private boolean mExpansionAffectsAlpha = true; private boolean mAnimateChange; private boolean mUpdatePending; - private boolean mTracking; private long mAnimationDuration = -1; private long mAnimationDelay; private Animator.AnimatorListener mAnimatorListener; @@ -526,7 +525,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump } public void onTrackingStarted() { - mTracking = true; mDarkenWhileDragging = !mKeyguardStateController.canDismissLockScreen(); if (!mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) { mAnimatingPanelExpansionOnUnlock = false; @@ -534,7 +532,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump } public void onExpandingFinished() { - mTracking = false; setUnocclusionAnimationRunning(false); } @@ -1450,8 +1447,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump pw.print(" expansionProgress="); pw.println(mTransitionToLockScreenFullShadeNotificationsProgress); - pw.print(" mTracking="); - pw.println(mTracking); pw.print(" mDefaultScrimAlpha="); pw.println(mDefaultScrimAlpha); pw.print(" mPanelExpansionFraction="); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java index f19650522bb40..d480fabe75b18 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java @@ -135,7 +135,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb private final PrimaryBouncerCallbackInteractor mPrimaryBouncerCallbackInteractor; private final PrimaryBouncerInteractor mPrimaryBouncerInteractor; private final BouncerView mPrimaryBouncerView; - private final Lazy mShadeController; + private final Lazy mShadeController; // Local cache of expansion events, to avoid duplicates private float mFraction = -1f; @@ -252,6 +252,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb private float mQsExpansion; final Set mCallbacks = new HashSet<>(); private boolean mIsModernBouncerEnabled; + private boolean mIsUnoccludeTransitionFlagEnabled; private OnDismissAction mAfterKeyguardGoneAction; private Runnable mKeyguardGoneCancelAction; @@ -329,6 +330,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb mFoldAodAnimationController = sysUIUnfoldComponent .map(SysUIUnfoldComponent::getFoldAodAnimationController).orElse(null); mIsModernBouncerEnabled = featureFlags.isEnabled(Flags.MODERN_BOUNCER); + mIsUnoccludeTransitionFlagEnabled = featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION); } @Override @@ -867,8 +869,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb // by a FLAG_DISMISS_KEYGUARD_ACTIVITY. reset(isOccluding /* hideBouncerWhenShowing*/); } - if (animate && !isOccluded && isShowing && !primaryBouncerIsShowing()) { - mCentralSurfaces.animateKeyguardUnoccluding(); + if (!mIsUnoccludeTransitionFlagEnabled) { + if (animate && !isOccluded && isShowing && !primaryBouncerIsShowing()) { + mCentralSurfaces.animateKeyguardUnoccluding(); + } } } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java index c94c97c9b638c..be4bbdf5adbc1 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerTest.java @@ -25,6 +25,7 @@ import android.test.suitebuilder.annotation.SmallTest; import android.testing.AndroidTestingRunner; import com.android.systemui.SysuiTestCase; +import com.android.systemui.flags.FeatureFlags; import com.android.systemui.plugins.ClockAnimations; import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.ScreenOffAnimationController; @@ -59,6 +60,8 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase { @Mock DozeParameters mDozeParameters; @Mock + FeatureFlags mFeatureFlags; + @Mock ScreenOffAnimationController mScreenOffAnimationController; @Captor private ArgumentCaptor mKeyguardUpdateMonitorCallbackCaptor; @@ -77,6 +80,7 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase { mKeyguardUpdateMonitor, mConfigurationController, mDozeParameters, + mFeatureFlags, mScreenOffAnimationController); } @@ -96,9 +100,9 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase { public void setTranslationYExcludingMedia_forwardsCallToView() { float translationY = 123f; - mController.setTranslationYExcludingMedia(translationY); + mController.setTranslationY(translationY, /* excludeMedia= */true); - verify(mKeyguardStatusView).setChildrenTranslationYExcludingMediaView(translationY); + verify(mKeyguardStatusView).setChildrenTranslationY(translationY, /* excludeMedia= */true); } @Test diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt index ce44f4d82d697..508aea51b6665 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt @@ -37,19 +37,23 @@ class KeyguardStatusViewTest : SysuiTestCase() { fun setChildrenTranslationYExcludingMediaView_mediaViewIsNotTranslated() { val translationY = 1234f - keyguardStatusView.setChildrenTranslationYExcludingMediaView(translationY) + keyguardStatusView.setChildrenTranslationY(translationY, /* excludeMedia= */true) assertThat(mediaView.translationY).isEqualTo(0) - } - - @Test - fun setChildrenTranslationYExcludingMediaView_childrenAreTranslated() { - val translationY = 1234f - - keyguardStatusView.setChildrenTranslationYExcludingMediaView(translationY) childrenExcludingMedia.forEach { assertThat(it.translationY).isEqualTo(translationY) } } -} \ No newline at end of file + + @Test + fun setChildrenTranslationYIncludeMediaView() { + val translationY = 1234f + + keyguardStatusView.setChildrenTranslationY(translationY, /* excludeMedia= */false) + + statusViewContainer.children.forEach { + assertThat(it.translationY).isEqualTo(translationY) + } + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt index 81950f1c22e5c..c54e456416c7d 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/DreamingToLockscreenTransitionViewModelTest.kt @@ -19,6 +19,7 @@ package com.android.systemui.keyguard.ui.viewmodel import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE +import com.android.systemui.animation.Interpolators.EMPHASIZED_DECELERATE import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository import com.android.systemui.keyguard.domain.interactor.DreamingTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor @@ -28,6 +29,8 @@ import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel.Companion.DREAM_OVERLAY_ALPHA import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel.Companion.DREAM_OVERLAY_TRANSLATION_Y +import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel.Companion.LOCKSCREEN_ALPHA +import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel.Companion.LOCKSCREEN_TRANSLATION_Y import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -65,10 +68,9 @@ class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() { repository.sendTransitionStep(step(0.5f)) repository.sendTransitionStep(step(1f)) - // Only two values should be present, since the dream overlay runs for a small fraction - // of - // the overall animation time - assertThat(values.size).isEqualTo(2) + // Only 3 values should be present, since the dream overlay runs for a small fraction + // of the overall animation time + assertThat(values.size).isEqualTo(3) assertThat(values[0]) .isEqualTo( EMPHASIZED_ACCELERATE.getInterpolation( @@ -81,6 +83,12 @@ class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() { animValue(0.3f, DREAM_OVERLAY_TRANSLATION_Y) ) * pixels ) + assertThat(values[2]) + .isEqualTo( + EMPHASIZED_ACCELERATE.getInterpolation( + animValue(0.5f, DREAM_OVERLAY_TRANSLATION_Y) + ) * pixels + ) job.cancel() } @@ -98,8 +106,7 @@ class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() { repository.sendTransitionStep(step(1f)) // Only two values should be present, since the dream overlay runs for a small fraction - // of - // the overall animation time + // of the overall animation time assertThat(values.size).isEqualTo(2) assertThat(values[0]).isEqualTo(1f - animValue(0f, DREAM_OVERLAY_ALPHA)) assertThat(values[1]).isEqualTo(1f - animValue(0.1f, DREAM_OVERLAY_ALPHA)) @@ -107,6 +114,77 @@ class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() { job.cancel() } + @Test + fun lockscreenFadeIn() = + runTest(UnconfinedTestDispatcher()) { + val values = mutableListOf() + + val job = underTest.lockscreenAlpha.onEach { values.add(it) }.launchIn(this) + + repository.sendTransitionStep(step(0f)) + repository.sendTransitionStep(step(0.1f)) + // Should start running here... + repository.sendTransitionStep(step(0.2f)) + repository.sendTransitionStep(step(0.3f)) + // ...up to here + repository.sendTransitionStep(step(1f)) + + // Only two values should be present, since the dream overlay runs for a small fraction + // of the overall animation time + assertThat(values.size).isEqualTo(2) + assertThat(values[0]).isEqualTo(animValue(0.2f, LOCKSCREEN_ALPHA)) + assertThat(values[1]).isEqualTo(animValue(0.3f, LOCKSCREEN_ALPHA)) + + job.cancel() + } + + @Test + fun lockscreenTranslationY() = + runTest(UnconfinedTestDispatcher()) { + val values = mutableListOf() + + val pixels = 100 + val job = + underTest.lockscreenTranslationY(pixels).onEach { values.add(it) }.launchIn(this) + + repository.sendTransitionStep(step(0f)) + repository.sendTransitionStep(step(0.3f)) + repository.sendTransitionStep(step(0.5f)) + repository.sendTransitionStep(step(1f)) + + assertThat(values.size).isEqualTo(4) + assertThat(values[0]) + .isEqualTo( + -pixels + + EMPHASIZED_DECELERATE.getInterpolation( + animValue(0f, LOCKSCREEN_TRANSLATION_Y) + ) * pixels + ) + assertThat(values[1]) + .isEqualTo( + -pixels + + EMPHASIZED_DECELERATE.getInterpolation( + animValue(0.3f, LOCKSCREEN_TRANSLATION_Y) + ) * pixels + ) + assertThat(values[2]) + .isEqualTo( + -pixels + + EMPHASIZED_DECELERATE.getInterpolation( + animValue(0.5f, LOCKSCREEN_TRANSLATION_Y) + ) * pixels + ) + assertThat(values[3]) + .isEqualTo( + -pixels + + EMPHASIZED_DECELERATE.getInterpolation( + animValue(1f, LOCKSCREEN_TRANSLATION_Y) + ) * pixels + ) + + job.cancel() + } + private fun animValue(stepValue: Float, params: AnimationParams): Float { val totalDuration = TO_LOCKSCREEN_DURATION val startValue = (params.startTime / totalDuration).toFloat() diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java index 01f13e6653187..ad993c391bcd1 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java @@ -104,6 +104,8 @@ import com.android.systemui.fragments.FragmentHostManager; import com.android.systemui.fragments.FragmentService; import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor; +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; +import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel; import com.android.systemui.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel; import com.android.systemui.media.controls.pipeline.MediaDataManager; import com.android.systemui.media.controls.ui.KeyguardMediaController; @@ -286,6 +288,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { @Mock private ViewTreeObserver mViewTreeObserver; @Mock private KeyguardBottomAreaViewModel mKeyguardBottomAreaViewModel; @Mock private KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor; + @Mock private DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel; + @Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor; @Mock private MotionEvent mDownMotionEvent; @Captor private ArgumentCaptor @@ -502,6 +506,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase { systemClock, mKeyguardBottomAreaViewModel, mKeyguardBottomAreaInteractor, + mDreamingToLockscreenTransitionViewModel, + mKeyguardTransitionInteractor, mDumpManager); mNotificationPanelViewController.initDependencies( mCentralSurfaces,