[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
This commit is contained in:
Matt Pietal
2022-12-16 15:25:51 +00:00
parent 4d3ec5c88d
commit 9b898b8f1a
16 changed files with 244 additions and 47 deletions

View File

@@ -1272,6 +1272,9 @@
translate into their final position. --> translate into their final position. -->
<dimen name="lockscreen_shade_keyguard_transition_distance">@dimen/lockscreen_shade_media_transition_distance</dimen> <dimen name="lockscreen_shade_keyguard_transition_distance">@dimen/lockscreen_shade_media_transition_distance</dimen>
<!-- DREAMING -> LOCKSCREEN transition: Amount to shift lockscreen content on entering -->
<dimen name="dreaming_to_lockscreen_transition_lockscreen_translation_y">40dp</dimen>
<!-- The amount of vertical offset for the keyguard during the full shade transition. --> <!-- The amount of vertical offset for the keyguard during the full shade transition. -->
<dimen name="lockscreen_shade_keyguard_transition_vertical_offset">0dp</dimen> <dimen name="lockscreen_shade_keyguard_transition_vertical_offset">0dp</dimen>

View File

@@ -16,6 +16,8 @@
package com.android.keyguard; package com.android.keyguard;
import static java.util.Collections.emptySet;
import android.content.Context; import android.content.Context;
import android.os.Trace; import android.os.Trace;
import android.util.AttributeSet; 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. */ /** Sets a translationY value on every child view except for the media view. */
public void setChildrenTranslationYExcludingMediaView(float translationY) { public void setChildrenTranslationY(float translationY, boolean excludeMedia) {
setChildrenTranslationYExcluding(translationY, Set.of(mMediaHostContainer)); setChildrenTranslationYExcluding(translationY,
excludeMedia ? Set.of(mMediaHostContainer) : emptySet());
} }
/** Sets a translationY value on every view except for the views in the provided set. */ /** Sets a translationY value on every view except for the views in the provided set. */

View File

@@ -20,6 +20,8 @@ import android.graphics.Rect;
import android.util.Slog; import android.util.Slog;
import com.android.keyguard.KeyguardClockSwitch.ClockSize; 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.plugins.ClockAnimations;
import com.android.systemui.statusbar.notification.AnimatableProperty; import com.android.systemui.statusbar.notification.AnimatableProperty;
import com.android.systemui.statusbar.notification.PropertyAnimator; import com.android.systemui.statusbar.notification.PropertyAnimator;
@@ -59,6 +61,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
KeyguardUpdateMonitor keyguardUpdateMonitor, KeyguardUpdateMonitor keyguardUpdateMonitor,
ConfigurationController configurationController, ConfigurationController configurationController,
DozeParameters dozeParameters, DozeParameters dozeParameters,
FeatureFlags featureFlags,
ScreenOffAnimationController screenOffAnimationController) { ScreenOffAnimationController screenOffAnimationController) {
super(keyguardStatusView); super(keyguardStatusView);
mKeyguardSliceViewController = keyguardSliceViewController; mKeyguardSliceViewController = keyguardSliceViewController;
@@ -67,6 +70,8 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
mConfigurationController = configurationController; mConfigurationController = configurationController;
mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController, mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController,
dozeParameters, screenOffAnimationController, /* animateYPos= */ true); dozeParameters, screenOffAnimationController, /* animateYPos= */ true);
mKeyguardVisibilityHelper.setOcclusionTransitionFlagEnabled(
featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION));
} }
@Override @Override
@@ -115,8 +120,8 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV
/** /**
* Sets a translationY on the views on the keyguard, except on the media view. * Sets a translationY on the views on the keyguard, except on the media view.
*/ */
public void setTranslationYExcludingMedia(float translationY) { public void setTranslationY(float translationY, boolean excludeMedia) {
mView.setChildrenTranslationYExcludingMediaView(translationY); mView.setChildrenTranslationY(translationY, excludeMedia);
} }
/** /**

View File

@@ -44,6 +44,7 @@ public class KeyguardVisibilityHelper {
private boolean mAnimateYPos; private boolean mAnimateYPos;
private boolean mKeyguardViewVisibilityAnimating; private boolean mKeyguardViewVisibilityAnimating;
private boolean mLastOccludedState = false; private boolean mLastOccludedState = false;
private boolean mIsUnoccludeTransitionFlagEnabled = false;
private final AnimationProperties mAnimationProperties = new AnimationProperties(); private final AnimationProperties mAnimationProperties = new AnimationProperties();
public KeyguardVisibilityHelper(View view, public KeyguardVisibilityHelper(View view,
@@ -62,6 +63,10 @@ public class KeyguardVisibilityHelper {
return mKeyguardViewVisibilityAnimating; return mKeyguardViewVisibilityAnimating;
} }
public void setOcclusionTransitionFlagEnabled(boolean enabled) {
mIsUnoccludeTransitionFlagEnabled = enabled;
}
/** /**
* Set the visibility of a keyguard view based on some new state. * Set the visibility of a keyguard view based on some new state.
*/ */
@@ -129,7 +134,7 @@ public class KeyguardVisibilityHelper {
// since it may need to be cancelled due to keyguard lifecycle events. // since it may need to be cancelled due to keyguard lifecycle events.
mScreenOffAnimationController.animateInKeyguard( mScreenOffAnimationController.animateInKeyguard(
mView, mAnimateKeyguardStatusViewVisibleEndRunnable); mView, mAnimateKeyguardStatusViewVisibleEndRunnable);
} else if (mLastOccludedState && !isOccluded) { } else if (!mIsUnoccludeTransitionFlagEnabled && mLastOccludedState && !isOccluded) {
// An activity was displayed over the lock screen, and has now gone away // An activity was displayed over the lock screen, and has now gone away
mView.setVisibility(View.VISIBLE); mView.setVisibility(View.VISIBLE);
mView.setAlpha(0f); mView.setAlpha(0f);
@@ -142,7 +147,9 @@ public class KeyguardVisibilityHelper {
.start(); .start();
} else { } else {
mView.setVisibility(View.VISIBLE); mView.setVisibility(View.VISIBLE);
mView.setAlpha(1f); if (!mIsUnoccludeTransitionFlagEnabled) {
mView.setAlpha(1f);
}
} }
} else { } else {
mView.setVisibility(View.GONE); mView.setVisibility(View.GONE);

View File

@@ -181,10 +181,6 @@ object Flags {
@JvmField @JvmField
val LIGHT_REVEAL_MIGRATION = unreleasedFlag(218, "light_reveal_migration", teamfood = false) val LIGHT_REVEAL_MIGRATION = unreleasedFlag(218, "light_reveal_migration", teamfood = false)
// TODO(b/262780002): Tracking Bug
@JvmField
val REVAMPED_WALLPAPER_UI = unreleasedFlag(222, "revamped_wallpaper_ui", teamfood = false)
/** Flag to control the migration of face auth to modern architecture. */ /** Flag to control the migration of face auth to modern architecture. */
// TODO(b/262838215): Tracking bug // TODO(b/262838215): Tracking bug
@JvmField val FACE_AUTH_REFACTOR = unreleasedFlag(220, "face_auth_refactor") @JvmField val FACE_AUTH_REFACTOR = unreleasedFlag(220, "face_auth_refactor")
@@ -193,6 +189,15 @@ object Flags {
// TODO(b/244313043): Tracking bug // TODO(b/244313043): Tracking bug
@JvmField val BIOMETRICS_ANIMATION_REVAMP = unreleasedFlag(221, "biometrics_animation_revamp") @JvmField val BIOMETRICS_ANIMATION_REVAMP = unreleasedFlag(221, "biometrics_animation_revamp")
// TODO(b/262780002): Tracking Bug
@JvmField
val REVAMPED_WALLPAPER_UI = unreleasedFlag(222, "revamped_wallpaper_ui", teamfood = false)
/** A different path for unocclusion transitions back to keyguard */
// TODO(b/262859270): Tracking Bug
@JvmField
val UNOCCLUSION_TRANSITION = unreleasedFlag(223, "unocclusion_transition", teamfood = false)
// 300 - power menu // 300 - power menu
// TODO(b/254512600): Tracking Bug // TODO(b/254512600): Tracking Bug
@JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite") @JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite")

View File

@@ -33,7 +33,7 @@ import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STR
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_AFTER_TIMEOUT;
import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE; import static com.android.internal.widget.LockPatternUtils.StrongAuthTracker.STRONG_AUTH_REQUIRED_FOR_UNATTENDED_UPDATE;
import static com.android.systemui.DejankUtils.whitelistIpcs; import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.keyguard.domain.interactor.DreamingTransitionInteractor.TO_LOCKSCREEN_DURATION_MS; import static com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel.LOCKSCREEN_ANIMATION_DURATION_MS;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
@@ -1232,7 +1232,7 @@ public class KeyguardViewMediator implements CoreStartable, Dumpable,
mDreamOpenAnimationDuration = context.getResources().getInteger( mDreamOpenAnimationDuration = context.getResources().getInteger(
com.android.internal.R.integer.config_dreamOpenAnimationDuration); com.android.internal.R.integer.config_dreamOpenAnimationDuration);
mDreamCloseAnimationDuration = (int) TO_LOCKSCREEN_DURATION_MS; mDreamCloseAnimationDuration = (int) LOCKSCREEN_ANIMATION_DURATION_MS;
} }
public void userActivity() { public void userActivity() {

View File

@@ -179,6 +179,5 @@ constructor(
companion object { companion object {
private val DEFAULT_DURATION = 500.milliseconds private val DEFAULT_DURATION = 500.milliseconds
val TO_LOCKSCREEN_DURATION = 1183.milliseconds val TO_LOCKSCREEN_DURATION = 1183.milliseconds
@JvmField val TO_LOCKSCREEN_DURATION_MS = TO_LOCKSCREEN_DURATION.inWholeMilliseconds
} }
} }

View File

@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.ui.viewmodel package com.android.systemui.keyguard.ui.viewmodel
import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE
import com.android.systemui.animation.Interpolators.EMPHASIZED_DECELERATE
import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.DreamingTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION import com.android.systemui.keyguard.domain.interactor.DreamingTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
@@ -46,12 +47,11 @@ constructor(
/** Dream overlay views alpha - fade out */ /** Dream overlay views alpha - fade out */
val dreamOverlayAlpha: Flow<Float> = flowForAnimation(DREAM_OVERLAY_ALPHA).map { 1f - it } val dreamOverlayAlpha: Flow<Float> = flowForAnimation(DREAM_OVERLAY_ALPHA).map { 1f - it }
/** Dream background alpha - fade out */
val dreamBackgroundAlpha: Flow<Float> = flowForAnimation(DREAM_BACKGROUND_ALPHA).map { 1f - it }
/** Lockscreen views y-translation */ /** Lockscreen views y-translation */
fun lockscreenTranslationY(translatePx: Int): Flow<Float> { fun lockscreenTranslationY(translatePx: Int): Flow<Float> {
return flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { it * translatePx } return flowForAnimation(LOCKSCREEN_TRANSLATION_Y).map { value ->
-translatePx + (EMPHASIZED_DECELERATE.getInterpolation(value) * translatePx)
}
} }
/** Lockscreen views alpha */ /** Lockscreen views alpha */
@@ -68,10 +68,12 @@ constructor(
companion object { companion object {
/* Length of time before ending the dream activity, in order to start unoccluding */ /* Length of time before ending the dream activity, in order to start unoccluding */
val DREAM_ANIMATION_DURATION = 250.milliseconds 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_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_TRANSLATION_Y = AnimationParams(duration = TO_LOCKSCREEN_DURATION)
val LOCKSCREEN_ALPHA = val LOCKSCREEN_ALPHA =
AnimationParams(startTime = 233.milliseconds, duration = 250.milliseconds) AnimationParams(startTime = 233.milliseconds, duration = 250.milliseconds)

View File

@@ -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.VibratorHelper.TOUCH_VIBRATION_ATTRIBUTES;
import static com.android.systemui.statusbar.notification.stack.StackStateAnimator.ANIMATION_DURATION_FOLD_TO_AOD; 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.DumpUtilsKt.asIndenting;
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
import static java.lang.Float.isNaN; 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.fragments.FragmentService;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor; 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.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
import com.android.systemui.media.controls.pipeline.MediaDataManager; import com.android.systemui.media.controls.pipeline.MediaDataManager;
import com.android.systemui.media.controls.ui.KeyguardMediaController; import com.android.systemui.media.controls.ui.KeyguardMediaController;
@@ -677,6 +682,12 @@ public final class NotificationPanelViewController implements Dumpable {
private boolean mGestureWaitForTouchSlop; private boolean mGestureWaitForTouchSlop;
private boolean mIgnoreXTouchSlop; private boolean mIgnoreXTouchSlop;
private boolean mExpandLatencyTracking; 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 */, private final Runnable mFlingCollapseRunnable = () -> fling(0, false /* expand */,
mNextCollapseSpeedUpFactor, false /* expandBecauseOfFalsing */); mNextCollapseSpeedUpFactor, false /* expandBecauseOfFalsing */);
@@ -692,6 +703,12 @@ public final class NotificationPanelViewController implements Dumpable {
} }
}; };
private final Consumer<TransitionStep> mDreamingToLockscreenTransition =
(TransitionStep step) -> {
mIsDreamToLockscreenTransitionRunning =
step.getTransitionState() == TransitionState.RUNNING;
};
@Inject @Inject
public NotificationPanelViewController(NotificationPanelView view, public NotificationPanelViewController(NotificationPanelView view,
@Main Handler handler, @Main Handler handler,
@@ -760,6 +777,8 @@ public final class NotificationPanelViewController implements Dumpable {
SystemClock systemClock, SystemClock systemClock,
KeyguardBottomAreaViewModel keyguardBottomAreaViewModel, KeyguardBottomAreaViewModel keyguardBottomAreaViewModel,
KeyguardBottomAreaInteractor keyguardBottomAreaInteractor, KeyguardBottomAreaInteractor keyguardBottomAreaInteractor,
DreamingToLockscreenTransitionViewModel dreamingToLockscreenTransitionViewModel,
KeyguardTransitionInteractor keyguardTransitionInteractor,
DumpManager dumpManager) { DumpManager dumpManager) {
keyguardStateController.addCallback(new KeyguardStateController.Callback() { keyguardStateController.addCallback(new KeyguardStateController.Callback() {
@Override @Override
@@ -775,6 +794,8 @@ public final class NotificationPanelViewController implements Dumpable {
mShadeLog = shadeLogger; mShadeLog = shadeLogger;
mShadeHeightLogger = shadeHeightLogger; mShadeHeightLogger = shadeHeightLogger;
mGutsManager = gutsManager; mGutsManager = gutsManager;
mDreamingToLockscreenTransitionViewModel = dreamingToLockscreenTransitionViewModel;
mKeyguardTransitionInteractor = keyguardTransitionInteractor;
mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() { mView.addOnAttachStateChangeListener(new View.OnAttachStateChangeListener() {
@Override @Override
public void onViewAttachedToWindow(View v) { public void onViewAttachedToWindow(View v) {
@@ -920,6 +941,8 @@ public final class NotificationPanelViewController implements Dumpable {
mNotificationPanelUnfoldAnimationController = unfoldComponent.map( mNotificationPanelUnfoldAnimationController = unfoldComponent.map(
SysUIUnfoldComponent::getNotificationPanelUnfoldAnimationController); SysUIUnfoldComponent::getNotificationPanelUnfoldAnimationController);
mUnocclusionTransitionFlagEnabled = featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION);
mQsFrameTranslateController = qsFrameTranslateController; mQsFrameTranslateController = qsFrameTranslateController;
updateUserSwitcherFlags(); updateUserSwitcherFlags();
mKeyguardBottomAreaViewModel = keyguardBottomAreaViewModel; mKeyguardBottomAreaViewModel = keyguardBottomAreaViewModel;
@@ -1072,6 +1095,18 @@ public final class NotificationPanelViewController implements Dumpable {
mKeyguardUnfoldTransition.ifPresent(u -> u.setup(mView)); mKeyguardUnfoldTransition.ifPresent(u -> u.setup(mView));
mNotificationPanelUnfoldAnimationController.ifPresent(controller -> mNotificationPanelUnfoldAnimationController.ifPresent(controller ->
controller.setup(mNotificationContainerParent)); controller.setup(mNotificationContainerParent));
if (mUnocclusionTransitionFlagEnabled) {
collectFlow(mView, mDreamingToLockscreenTransitionViewModel.getLockscreenAlpha(),
dreamingToLockscreenTransitionAlpha(mNotificationStackScrollLayoutController));
collectFlow(mView, mDreamingToLockscreenTransitionViewModel.lockscreenTranslationY(
mDreamingToLockscreenTransitionTranslationY),
dreamingToLockscreenTransitionY(mNotificationStackScrollLayoutController));
collectFlow(mView, mKeyguardTransitionInteractor.getDreamingToLockscreenTransition(),
mDreamingToLockscreenTransition);
}
} }
@VisibleForTesting @VisibleForTesting
@@ -1106,6 +1141,8 @@ public final class NotificationPanelViewController implements Dumpable {
mUdfpsMaxYBurnInOffset = mResources.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y); mUdfpsMaxYBurnInOffset = mResources.getDimensionPixelSize(R.dimen.udfps_burn_in_offset_y);
mSplitShadeScrimTransitionDistance = mResources.getDimensionPixelSize( mSplitShadeScrimTransitionDistance = mResources.getDimensionPixelSize(
R.dimen.split_shade_scrim_transition_distance); R.dimen.split_shade_scrim_transition_distance);
mDreamingToLockscreenTransitionTranslationY = mResources.getDimensionPixelSize(
R.dimen.dreaming_to_lockscreen_transition_lockscreen_translation_y);
} }
private void updateViewControllers(KeyguardStatusView keyguardStatusView, private void updateViewControllers(KeyguardStatusView keyguardStatusView,
@@ -1769,10 +1806,14 @@ public final class NotificationPanelViewController implements Dumpable {
} }
private void updateClock() { private void updateClock() {
if (mIsDreamToLockscreenTransitionRunning) {
return;
}
float alpha = mClockPositionResult.clockAlpha * mKeyguardOnlyContentAlpha; float alpha = mClockPositionResult.clockAlpha * mKeyguardOnlyContentAlpha;
mKeyguardStatusViewController.setAlpha(alpha); mKeyguardStatusViewController.setAlpha(alpha);
mKeyguardStatusViewController mKeyguardStatusViewController
.setTranslationYExcludingMedia(mKeyguardOnlyTransitionTranslationY); .setTranslationY(mKeyguardOnlyTransitionTranslationY, /* excludeMedia= */true);
if (mKeyguardQsUserSwitchController != null) { if (mKeyguardQsUserSwitchController != null) {
mKeyguardQsUserSwitchController.setAlpha(alpha); mKeyguardQsUserSwitchController.setAlpha(alpha);
} }
@@ -2656,7 +2697,9 @@ public final class NotificationPanelViewController implements Dumpable {
} else if (statusBarState == KEYGUARD } else if (statusBarState == KEYGUARD
|| statusBarState == StatusBarState.SHADE_LOCKED) { || statusBarState == StatusBarState.SHADE_LOCKED) {
mKeyguardBottomArea.setVisibility(View.VISIBLE); mKeyguardBottomArea.setVisibility(View.VISIBLE);
mKeyguardBottomArea.setAlpha(1f); if (!mIsDreamToLockscreenTransitionRunning) {
mKeyguardBottomArea.setAlpha(1f);
}
} else { } else {
mKeyguardBottomArea.setVisibility(View.GONE); mKeyguardBottomArea.setVisibility(View.GONE);
} }
@@ -3523,6 +3566,9 @@ public final class NotificationPanelViewController implements Dumpable {
} }
private void updateNotificationTranslucency() { private void updateNotificationTranslucency() {
if (mIsDreamToLockscreenTransitionRunning) {
return;
}
float alpha = 1f; float alpha = 1f;
if (mClosingWithAlphaFadeOut && !mExpandingFromHeadsUp if (mClosingWithAlphaFadeOut && !mExpandingFromHeadsUp
&& !mHeadsUpManager.hasPinnedHeadsUp()) { && !mHeadsUpManager.hasPinnedHeadsUp()) {
@@ -3578,6 +3624,9 @@ public final class NotificationPanelViewController implements Dumpable {
} }
private void updateKeyguardBottomAreaAlpha() { private void updateKeyguardBottomAreaAlpha() {
if (mIsDreamToLockscreenTransitionRunning) {
return;
}
// There are two possible panel expansion behaviors: // There are two possible panel expansion behaviors:
// • User dragging up to unlock: we want to fade out as quick as possible // • 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. // (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() { private void onExpandingFinished() {
mScrimController.onExpandingFinished(); if (!mUnocclusionTransitionFlagEnabled) {
mScrimController.onExpandingFinished();
}
mNotificationStackScrollLayoutController.onExpansionStopped(); mNotificationStackScrollLayoutController.onExpansionStopped();
mHeadsUpManager.onExpandingFinished(); mHeadsUpManager.onExpandingFinished();
mConversationNotificationManager.onNotificationPanelExpandStateChanged(isFullyCollapsed()); mConversationNotificationManager.onNotificationPanelExpandStateChanged(isFullyCollapsed());
@@ -5805,6 +5856,32 @@ public final class NotificationPanelViewController implements Dumpable {
mCurrentPanelState = state; mCurrentPanelState = state;
} }
private Consumer<Float> 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<Float> dreamingToLockscreenTransitionY(
NotificationStackScrollLayoutController stackScroller) {
return (Float translationY) -> {
mKeyguardStatusViewController.setTranslationY(translationY, /* excludeMedia= */false);
stackScroller.setTranslationY(translationY);
};
}
@VisibleForTesting @VisibleForTesting
StatusBarStateController getStatusBarStateController() { StatusBarStateController getStatusBarStateController() {
return mStatusBarStateController; return mStatusBarStateController;

View File

@@ -916,6 +916,11 @@ public class NotificationStackScrollLayoutController {
return mView.getTranslationX(); return mView.getTranslationX();
} }
/** Set view y-translation */
public void setTranslationY(float translationY) {
mView.setTranslationY(translationY);
}
public int indexOfChild(View view) { public int indexOfChild(View view) {
return mView.indexOfChild(view); return mView.indexOfChild(view);
} }

View File

@@ -232,7 +232,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
private boolean mExpansionAffectsAlpha = true; private boolean mExpansionAffectsAlpha = true;
private boolean mAnimateChange; private boolean mAnimateChange;
private boolean mUpdatePending; private boolean mUpdatePending;
private boolean mTracking;
private long mAnimationDuration = -1; private long mAnimationDuration = -1;
private long mAnimationDelay; private long mAnimationDelay;
private Animator.AnimatorListener mAnimatorListener; private Animator.AnimatorListener mAnimatorListener;
@@ -526,7 +525,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
} }
public void onTrackingStarted() { public void onTrackingStarted() {
mTracking = true;
mDarkenWhileDragging = !mKeyguardStateController.canDismissLockScreen(); mDarkenWhileDragging = !mKeyguardStateController.canDismissLockScreen();
if (!mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) { if (!mKeyguardUnlockAnimationController.isPlayingCannedUnlockAnimation()) {
mAnimatingPanelExpansionOnUnlock = false; mAnimatingPanelExpansionOnUnlock = false;
@@ -534,7 +532,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
} }
public void onExpandingFinished() { public void onExpandingFinished() {
mTracking = false;
setUnocclusionAnimationRunning(false); setUnocclusionAnimationRunning(false);
} }
@@ -1450,8 +1447,6 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump
pw.print(" expansionProgress="); pw.print(" expansionProgress=");
pw.println(mTransitionToLockScreenFullShadeNotificationsProgress); pw.println(mTransitionToLockScreenFullShadeNotificationsProgress);
pw.print(" mTracking=");
pw.println(mTracking);
pw.print(" mDefaultScrimAlpha="); pw.print(" mDefaultScrimAlpha=");
pw.println(mDefaultScrimAlpha); pw.println(mDefaultScrimAlpha);
pw.print(" mPanelExpansionFraction="); pw.print(" mPanelExpansionFraction=");

View File

@@ -135,7 +135,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
private final PrimaryBouncerCallbackInteractor mPrimaryBouncerCallbackInteractor; private final PrimaryBouncerCallbackInteractor mPrimaryBouncerCallbackInteractor;
private final PrimaryBouncerInteractor mPrimaryBouncerInteractor; private final PrimaryBouncerInteractor mPrimaryBouncerInteractor;
private final BouncerView mPrimaryBouncerView; private final BouncerView mPrimaryBouncerView;
private final Lazy<com.android.systemui.shade.ShadeController> mShadeController; private final Lazy<ShadeController> mShadeController;
// Local cache of expansion events, to avoid duplicates // Local cache of expansion events, to avoid duplicates
private float mFraction = -1f; private float mFraction = -1f;
@@ -252,6 +252,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
private float mQsExpansion; private float mQsExpansion;
final Set<KeyguardViewManagerCallback> mCallbacks = new HashSet<>(); final Set<KeyguardViewManagerCallback> mCallbacks = new HashSet<>();
private boolean mIsModernBouncerEnabled; private boolean mIsModernBouncerEnabled;
private boolean mIsUnoccludeTransitionFlagEnabled;
private OnDismissAction mAfterKeyguardGoneAction; private OnDismissAction mAfterKeyguardGoneAction;
private Runnable mKeyguardGoneCancelAction; private Runnable mKeyguardGoneCancelAction;
@@ -329,6 +330,7 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
mFoldAodAnimationController = sysUIUnfoldComponent mFoldAodAnimationController = sysUIUnfoldComponent
.map(SysUIUnfoldComponent::getFoldAodAnimationController).orElse(null); .map(SysUIUnfoldComponent::getFoldAodAnimationController).orElse(null);
mIsModernBouncerEnabled = featureFlags.isEnabled(Flags.MODERN_BOUNCER); mIsModernBouncerEnabled = featureFlags.isEnabled(Flags.MODERN_BOUNCER);
mIsUnoccludeTransitionFlagEnabled = featureFlags.isEnabled(Flags.UNOCCLUSION_TRANSITION);
} }
@Override @Override
@@ -867,8 +869,10 @@ public class StatusBarKeyguardViewManager implements RemoteInputController.Callb
// by a FLAG_DISMISS_KEYGUARD_ACTIVITY. // by a FLAG_DISMISS_KEYGUARD_ACTIVITY.
reset(isOccluding /* hideBouncerWhenShowing*/); reset(isOccluding /* hideBouncerWhenShowing*/);
} }
if (animate && !isOccluded && isShowing && !primaryBouncerIsShowing()) { if (!mIsUnoccludeTransitionFlagEnabled) {
mCentralSurfaces.animateKeyguardUnoccluding(); if (animate && !isOccluded && isShowing && !primaryBouncerIsShowing()) {
mCentralSurfaces.animateKeyguardUnoccluding();
}
} }
} }

View File

@@ -25,6 +25,7 @@ import android.test.suitebuilder.annotation.SmallTest;
import android.testing.AndroidTestingRunner; import android.testing.AndroidTestingRunner;
import com.android.systemui.SysuiTestCase; import com.android.systemui.SysuiTestCase;
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.plugins.ClockAnimations; import com.android.systemui.plugins.ClockAnimations;
import com.android.systemui.statusbar.phone.DozeParameters; import com.android.systemui.statusbar.phone.DozeParameters;
import com.android.systemui.statusbar.phone.ScreenOffAnimationController; import com.android.systemui.statusbar.phone.ScreenOffAnimationController;
@@ -59,6 +60,8 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
@Mock @Mock
DozeParameters mDozeParameters; DozeParameters mDozeParameters;
@Mock @Mock
FeatureFlags mFeatureFlags;
@Mock
ScreenOffAnimationController mScreenOffAnimationController; ScreenOffAnimationController mScreenOffAnimationController;
@Captor @Captor
private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallbackCaptor; private ArgumentCaptor<KeyguardUpdateMonitorCallback> mKeyguardUpdateMonitorCallbackCaptor;
@@ -77,6 +80,7 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
mKeyguardUpdateMonitor, mKeyguardUpdateMonitor,
mConfigurationController, mConfigurationController,
mDozeParameters, mDozeParameters,
mFeatureFlags,
mScreenOffAnimationController); mScreenOffAnimationController);
} }
@@ -96,9 +100,9 @@ public class KeyguardStatusViewControllerTest extends SysuiTestCase {
public void setTranslationYExcludingMedia_forwardsCallToView() { public void setTranslationYExcludingMedia_forwardsCallToView() {
float translationY = 123f; float translationY = 123f;
mController.setTranslationYExcludingMedia(translationY); mController.setTranslationY(translationY, /* excludeMedia= */true);
verify(mKeyguardStatusView).setChildrenTranslationYExcludingMediaView(translationY); verify(mKeyguardStatusView).setChildrenTranslationY(translationY, /* excludeMedia= */true);
} }
@Test @Test

View File

@@ -37,19 +37,23 @@ class KeyguardStatusViewTest : SysuiTestCase() {
fun setChildrenTranslationYExcludingMediaView_mediaViewIsNotTranslated() { fun setChildrenTranslationYExcludingMediaView_mediaViewIsNotTranslated() {
val translationY = 1234f val translationY = 1234f
keyguardStatusView.setChildrenTranslationYExcludingMediaView(translationY) keyguardStatusView.setChildrenTranslationY(translationY, /* excludeMedia= */true)
assertThat(mediaView.translationY).isEqualTo(0) assertThat(mediaView.translationY).isEqualTo(0)
}
@Test
fun setChildrenTranslationYExcludingMediaView_childrenAreTranslated() {
val translationY = 1234f
keyguardStatusView.setChildrenTranslationYExcludingMediaView(translationY)
childrenExcludingMedia.forEach { childrenExcludingMedia.forEach {
assertThat(it.translationY).isEqualTo(translationY) assertThat(it.translationY).isEqualTo(translationY)
} }
} }
}
@Test
fun setChildrenTranslationYIncludeMediaView() {
val translationY = 1234f
keyguardStatusView.setChildrenTranslationY(translationY, /* excludeMedia= */false)
statusViewContainer.children.forEach {
assertThat(it.translationY).isEqualTo(translationY)
}
}
}

View File

@@ -19,6 +19,7 @@ package com.android.systemui.keyguard.ui.viewmodel
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase import com.android.systemui.SysuiTestCase
import com.android.systemui.animation.Interpolators.EMPHASIZED_ACCELERATE 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.data.repository.FakeKeyguardTransitionRepository
import com.android.systemui.keyguard.domain.interactor.DreamingTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION import com.android.systemui.keyguard.domain.interactor.DreamingTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor 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.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_ALPHA
import com.android.systemui.keyguard.ui.viewmodel.DreamingToLockscreenTransitionViewModel.Companion.DREAM_OVERLAY_TRANSLATION_Y 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 com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
@@ -65,10 +68,9 @@ class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() {
repository.sendTransitionStep(step(0.5f)) repository.sendTransitionStep(step(0.5f))
repository.sendTransitionStep(step(1f)) repository.sendTransitionStep(step(1f))
// Only two values should be present, since the dream overlay runs for a small fraction // Only 3 values should be present, since the dream overlay runs for a small fraction
// of // of the overall animation time
// the overall animation time assertThat(values.size).isEqualTo(3)
assertThat(values.size).isEqualTo(2)
assertThat(values[0]) assertThat(values[0])
.isEqualTo( .isEqualTo(
EMPHASIZED_ACCELERATE.getInterpolation( EMPHASIZED_ACCELERATE.getInterpolation(
@@ -81,6 +83,12 @@ class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() {
animValue(0.3f, DREAM_OVERLAY_TRANSLATION_Y) animValue(0.3f, DREAM_OVERLAY_TRANSLATION_Y)
) * pixels ) * pixels
) )
assertThat(values[2])
.isEqualTo(
EMPHASIZED_ACCELERATE.getInterpolation(
animValue(0.5f, DREAM_OVERLAY_TRANSLATION_Y)
) * pixels
)
job.cancel() job.cancel()
} }
@@ -98,8 +106,7 @@ class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() {
repository.sendTransitionStep(step(1f)) repository.sendTransitionStep(step(1f))
// Only two values should be present, since the dream overlay runs for a small fraction // Only two values should be present, since the dream overlay runs for a small fraction
// of // of the overall animation time
// the overall animation time
assertThat(values.size).isEqualTo(2) assertThat(values.size).isEqualTo(2)
assertThat(values[0]).isEqualTo(1f - animValue(0f, DREAM_OVERLAY_ALPHA)) assertThat(values[0]).isEqualTo(1f - animValue(0f, DREAM_OVERLAY_ALPHA))
assertThat(values[1]).isEqualTo(1f - animValue(0.1f, DREAM_OVERLAY_ALPHA)) assertThat(values[1]).isEqualTo(1f - animValue(0.1f, DREAM_OVERLAY_ALPHA))
@@ -107,6 +114,77 @@ class DreamingToLockscreenTransitionViewModelTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun lockscreenFadeIn() =
runTest(UnconfinedTestDispatcher()) {
val values = mutableListOf<Float>()
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<Float>()
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 { private fun animValue(stepValue: Float, params: AnimationParams): Float {
val totalDuration = TO_LOCKSCREEN_DURATION val totalDuration = TO_LOCKSCREEN_DURATION
val startValue = (params.startTime / totalDuration).toFloat() val startValue = (params.startTime / totalDuration).toFloat()

View File

@@ -104,6 +104,8 @@ import com.android.systemui.fragments.FragmentHostManager;
import com.android.systemui.fragments.FragmentService; import com.android.systemui.fragments.FragmentService;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController; import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
import com.android.systemui.keyguard.domain.interactor.KeyguardBottomAreaInteractor; 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.keyguard.ui.viewmodel.KeyguardBottomAreaViewModel;
import com.android.systemui.media.controls.pipeline.MediaDataManager; import com.android.systemui.media.controls.pipeline.MediaDataManager;
import com.android.systemui.media.controls.ui.KeyguardMediaController; import com.android.systemui.media.controls.ui.KeyguardMediaController;
@@ -286,6 +288,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
@Mock private ViewTreeObserver mViewTreeObserver; @Mock private ViewTreeObserver mViewTreeObserver;
@Mock private KeyguardBottomAreaViewModel mKeyguardBottomAreaViewModel; @Mock private KeyguardBottomAreaViewModel mKeyguardBottomAreaViewModel;
@Mock private KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor; @Mock private KeyguardBottomAreaInteractor mKeyguardBottomAreaInteractor;
@Mock private DreamingToLockscreenTransitionViewModel mDreamingToLockscreenTransitionViewModel;
@Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
@Mock private MotionEvent mDownMotionEvent; @Mock private MotionEvent mDownMotionEvent;
@Captor @Captor
private ArgumentCaptor<NotificationStackScrollLayout.OnEmptySpaceClickListener> private ArgumentCaptor<NotificationStackScrollLayout.OnEmptySpaceClickListener>
@@ -502,6 +506,8 @@ public class NotificationPanelViewControllerTest extends SysuiTestCase {
systemClock, systemClock,
mKeyguardBottomAreaViewModel, mKeyguardBottomAreaViewModel,
mKeyguardBottomAreaInteractor, mKeyguardBottomAreaInteractor,
mDreamingToLockscreenTransitionViewModel,
mKeyguardTransitionInteractor,
mDumpManager); mDumpManager);
mNotificationPanelViewController.initDependencies( mNotificationPanelViewController.initDependencies(
mCentralSurfaces, mCentralSurfaces,