diff options
27 files changed, 692 insertions, 174 deletions
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 1b09c6afeafc..ef0053da53a9 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -766,6 +766,8 @@ <dimen name="keyguard_clock_switch_y_shift">14dp</dimen> <!-- When large clock is showing, offset the smartspace by this amount --> <dimen name="keyguard_smartspace_top_offset">12dp</dimen> + <!-- The amount to translate lockscreen elements on the GONE->AOD transition --> + <dimen name="keyguard_enter_from_top_translation_y">-100dp</dimen> <dimen name="notification_scrim_corner_radius">32dp</dimen> diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt index 01a75d9e0f16..e47d36f76a14 100644 --- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt +++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt @@ -15,6 +15,8 @@ */ package com.android.keyguard +import com.android.systemui.keyguard.shared.model.KeyguardState.AOD +import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import android.content.BroadcastReceiver import android.content.Context import android.content.Intent @@ -37,7 +39,7 @@ import com.android.systemui.dagger.qualifiers.Background import com.android.systemui.dagger.qualifiers.DisplaySpecific import com.android.systemui.dagger.qualifiers.Main import com.android.systemui.flags.FeatureFlags -import com.android.systemui.flags.Flags.DOZING_MIGRATION_1 +import com.android.systemui.flags.Flags.MIGRATE_KEYGUARD_STATUS_VIEW import com.android.systemui.flags.Flags.REGION_SAMPLING import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor @@ -61,6 +63,7 @@ import kotlinx.coroutines.DisposableHandle import kotlinx.coroutines.Job import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.merge import kotlinx.coroutines.launch import java.util.Locale import java.util.TimeZone @@ -297,7 +300,7 @@ constructor( object : KeyguardUpdateMonitorCallback() { override fun onKeyguardVisibilityChanged(visible: Boolean) { isKeyguardVisible = visible - if (!featureFlags.isEnabled(DOZING_MIGRATION_1)) { + if (!featureFlags.isEnabled(MIGRATE_KEYGUARD_STATUS_VIEW)) { if (!isKeyguardVisible) { clock?.run { smallClock.animations.doze(if (isDozing) 1f else 0f) @@ -342,9 +345,9 @@ constructor( keyguardUpdateMonitor.registerCallback(keyguardUpdateMonitorCallback) disposableHandle = parent.repeatWhenAttached { - repeatOnLifecycle(Lifecycle.State.STARTED) { + repeatOnLifecycle(Lifecycle.State.CREATED) { listenForDozing(this) - if (featureFlags.isEnabled(DOZING_MIGRATION_1)) { + if (featureFlags.isEnabled(MIGRATE_KEYGUARD_STATUS_VIEW)) { listenForDozeAmountTransition(this) listenForAnyStateToAodTransition(this) } else { @@ -454,8 +457,9 @@ constructor( @VisibleForTesting internal fun listenForAnyStateToAodTransition(scope: CoroutineScope): Job { return scope.launch { - keyguardTransitionInteractor.anyStateToAodTransition - .filter { it.transitionState == TransitionState.FINISHED } + keyguardTransitionInteractor.transitionStepsToState(AOD) + .filter { it.transitionState == TransitionState.STARTED } + .filter { it.from != LOCKSCREEN } .collect { handleDoze(1f) } } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java index 79642bdae1ce..758d1fef6e2e 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardStatusViewController.java @@ -54,6 +54,9 @@ import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.flags.Flags; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor; +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.plugins.ClockController; import com.android.systemui.power.domain.interactor.PowerInteractor; import com.android.systemui.power.shared.model.ScreenPowerState; @@ -102,10 +105,11 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV private final Rect mClipBounds = new Rect(); private final KeyguardInteractor mKeyguardInteractor; private final PowerInteractor mPowerInteractor; + private final KeyguardTransitionInteractor mKeyguardTransitionInteractor; private Boolean mSplitShadeEnabled = false; private Boolean mStatusViewCentered = true; - + private boolean mGoneToAodTransitionRunning = false; private DumpManager mDumpManager; private final TransitionListenerAdapter mKeyguardStatusAlignmentTransitionListener = @@ -135,6 +139,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV FeatureFlags featureFlags, InteractionJankMonitor interactionJankMonitor, KeyguardInteractor keyguardInteractor, + KeyguardTransitionInteractor keyguardTransitionInteractor, DumpManager dumpManager, PowerInteractor powerInteractor) { super(keyguardStatusView); @@ -144,12 +149,13 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV mConfigurationController = configurationController; mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController, dozeParameters, screenOffAnimationController, /* animateYPos= */ true, - logger.getBuffer()); + featureFlags, logger.getBuffer()); mInteractionJankMonitor = interactionJankMonitor; mFeatureFlags = featureFlags; mDumpManager = dumpManager; mKeyguardInteractor = keyguardInteractor; mPowerInteractor = powerInteractor; + mKeyguardTransitionInteractor = keyguardTransitionInteractor; } @Override @@ -199,6 +205,15 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV dozeTimeTick(); } }, context); + + collectFlow(mView, mKeyguardTransitionInteractor.getGoneToAodTransition(), + (TransitionStep step) -> { + if (step.getTransitionState() == TransitionState.RUNNING) { + mGoneToAodTransitionRunning = true; + } else { + mGoneToAodTransitionRunning = false; + } + }, context); } public KeyguardStatusView getView() { @@ -266,7 +281,7 @@ public class KeyguardStatusViewController extends ViewController<KeyguardStatusV * Set keyguard status view alpha. */ public void setAlpha(float alpha) { - if (!mKeyguardVisibilityHelper.isVisibilityAnimating()) { + if (!mKeyguardVisibilityHelper.isVisibilityAnimating() && !mGoneToAodTransitionRunning) { mView.setAlpha(alpha); } } diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java index c64ae0106b4a..d524e4a8c408 100644 --- a/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java +++ b/packages/SystemUI/src/com/android/keyguard/KeyguardVisibilityHelper.java @@ -23,6 +23,8 @@ import android.util.Property; import android.view.View; import com.android.app.animation.Interpolators; +import com.android.systemui.flags.FeatureFlags; +import com.android.systemui.flags.Flags; import com.android.systemui.log.LogBuffer; import com.android.systemui.log.core.LogLevel; import com.android.systemui.statusbar.StatusBarState; @@ -53,6 +55,7 @@ public class KeyguardVisibilityHelper { private boolean mKeyguardViewVisibilityAnimating; private boolean mLastOccludedState = false; private final AnimationProperties mAnimationProperties = new AnimationProperties(); + private final FeatureFlags mFeatureFlags; private final LogBuffer mLogBuffer; public KeyguardVisibilityHelper(View view, @@ -60,12 +63,14 @@ public class KeyguardVisibilityHelper { DozeParameters dozeParameters, ScreenOffAnimationController screenOffAnimationController, boolean animateYPos, + FeatureFlags featureFlags, LogBuffer logBuffer) { mView = view; mKeyguardStateController = keyguardStateController; mDozeParameters = dozeParameters; mScreenOffAnimationController = screenOffAnimationController; mAnimateYPos = animateYPos; + mFeatureFlags = featureFlags; mLogBuffer = logBuffer; } @@ -162,13 +167,17 @@ public class KeyguardVisibilityHelper { animProps, true /* animate */); } else if (mScreenOffAnimationController.shouldAnimateInKeyguard()) { - log("ScreenOff transition"); - mKeyguardViewVisibilityAnimating = true; + if (mFeatureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) { + log("Using GoneToAodTransition"); + mKeyguardViewVisibilityAnimating = false; + } else { + log("ScreenOff transition"); + mKeyguardViewVisibilityAnimating = true; - // Ask the screen off animation controller to animate the keyguard visibility for us - // since it may need to be cancelled due to keyguard lifecycle events. - mScreenOffAnimationController.animateInKeyguard( - mView, mSetVisibleEndRunnable); + // Ask the screen off animation controller to animate the keyguard visibility + // for us since it may need to be cancelled due to keyguard lifecycle events. + mScreenOffAnimationController.animateInKeyguard(mView, mSetVisibleEndRunnable); + } } else { log("Direct set Visibility to VISIBLE"); mView.setVisibility(View.VISIBLE); diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt index 86bf368791bc..a511713eddd3 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewConfigurator.kt @@ -20,6 +20,7 @@ package com.android.systemui.keyguard import android.content.Context import android.view.LayoutInflater import android.view.View +import com.android.internal.jank.InteractionJankMonitor import com.android.keyguard.KeyguardStatusView import com.android.keyguard.KeyguardStatusViewController import com.android.keyguard.LockIconView @@ -71,6 +72,7 @@ constructor( private val keyguardIndicationController: KeyguardIndicationController, private val lockIconViewController: LockIconViewController, private val shadeInteractor: ShadeInteractor, + private val interactionJankMonitor: InteractionJankMonitor ) : CoreStartable { private var rootViewHandle: DisposableHandle? = null @@ -140,6 +142,7 @@ constructor( keyguardStateController, shadeInteractor, { keyguardStatusViewController!!.getClockController() }, + interactionJankMonitor, ) } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt index 38eb730d1498..6e0aa4c7682d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAodTransitionInteractor.kt @@ -26,10 +26,11 @@ import com.android.systemui.keyguard.shared.model.DozeStateModel import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.util.kotlin.Utils.Companion.toTriple import com.android.systemui.util.kotlin.sample +import javax.inject.Inject +import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch -import javax.inject.Inject @SysUISingleton class FromAodTransitionInteractor @@ -86,15 +87,19 @@ constructor( } } } - override fun getDefaultAnimatorForTransitionsToState(toState: KeyguardState): ValueAnimator { return ValueAnimator().apply { interpolator = Interpolators.LINEAR - duration = TRANSITION_DURATION_MS + duration = + when (toState) { + KeyguardState.LOCKSCREEN -> TO_LOCKSCREEN_DURATION + else -> DEFAULT_DURATION + }.inWholeMilliseconds } } companion object { - private const val TRANSITION_DURATION_MS = 500L + val TO_LOCKSCREEN_DURATION = 500.milliseconds + private val DEFAULT_DURATION = 500.milliseconds } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt index ad51e74090d9..c67153a5963d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromGoneTransitionInteractor.kt @@ -114,7 +114,8 @@ constructor( .collect { (isAsleep, lastStartedStep, isAodAvailable) -> if (lastStartedStep.to == KeyguardState.GONE && isAsleep) { startTransitionTo( - if (isAodAvailable) KeyguardState.AOD else KeyguardState.DOZING + if (isAodAvailable) KeyguardState.AOD else KeyguardState.DOZING, + resetIfCancelled = true, ) } } @@ -127,6 +128,7 @@ constructor( duration = when (toState) { KeyguardState.DREAMING -> TO_DREAMING_DURATION + KeyguardState.AOD -> TO_AOD_DURATION else -> DEFAULT_DURATION }.inWholeMilliseconds } @@ -134,5 +136,6 @@ constructor( companion object { private val DEFAULT_DURATION = 500.milliseconds val TO_DREAMING_DURATION = 933.milliseconds + val TO_AOD_DURATION = 1100.milliseconds } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt index 660bd84006d7..c39a4c9c4172 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromLockscreenTransitionInteractor.kt @@ -33,6 +33,9 @@ import com.android.systemui.shade.data.repository.ShadeRepository import com.android.systemui.util.kotlin.Utils.Companion.toQuad import com.android.systemui.util.kotlin.Utils.Companion.toTriple import com.android.systemui.util.kotlin.sample +import java.util.UUID +import javax.inject.Inject +import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.combine @@ -40,9 +43,6 @@ import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onStart import kotlinx.coroutines.launch -import java.util.UUID -import javax.inject.Inject -import kotlin.time.Duration.Companion.milliseconds @SysUISingleton class FromLockscreenTransitionInteractor @@ -355,6 +355,7 @@ constructor( when (toState) { KeyguardState.DREAMING -> TO_DREAMING_DURATION KeyguardState.OCCLUDED -> TO_OCCLUDED_DURATION + KeyguardState.AOD -> TO_AOD_DURATION else -> DEFAULT_DURATION }.inWholeMilliseconds } @@ -364,5 +365,6 @@ constructor( private val DEFAULT_DURATION = 400.milliseconds val TO_DREAMING_DURATION = 933.milliseconds val TO_OCCLUDED_DURATION = 450.milliseconds + val TO_AOD_DURATION = 500.milliseconds } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt index 6e19fdbefab5..b953b4879a4a 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardInteractor.kt @@ -39,7 +39,6 @@ import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel import com.android.systemui.keyguard.shared.model.DozeStateModel import com.android.systemui.keyguard.shared.model.DozeStateModel.Companion.isDozeOff import com.android.systemui.keyguard.shared.model.DozeTransitionModel -import com.android.systemui.keyguard.shared.model.KeyguardRootViewVisibilityState import com.android.systemui.keyguard.shared.model.StatusBarState import com.android.systemui.power.domain.interactor.PowerInteractor import com.android.systemui.res.R @@ -49,6 +48,8 @@ import com.android.systemui.scene.shared.model.SceneKey import com.android.systemui.shade.data.repository.ShadeRepository import com.android.systemui.statusbar.CommandQueue import com.android.systemui.util.kotlin.sample +import javax.inject.Inject +import javax.inject.Provider import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.delay @@ -64,8 +65,6 @@ import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.onStart -import javax.inject.Inject -import javax.inject.Provider /** * Encapsulates business-logic related to the keyguard but not to a more specific part within it. @@ -148,9 +147,7 @@ constructor( .combine(dozeTransitionModel) { isDreaming, dozeTransitionModel -> isDreaming && isDozeOff(dozeTransitionModel.to) } - .sample(powerInteractor.isAwake) { isAbleToDream, isAwake -> - isAbleToDream && isAwake - } + .sample(powerInteractor.isAwake) { isAbleToDream, isAwake -> isAbleToDream && isAwake } .flatMapLatest { isAbleToDream -> flow { delay(50) @@ -217,11 +214,8 @@ constructor( val faceSensorLocation: Flow<Point?> = repository.faceSensorLocation /** Notifies when a new configuration is set */ - val configurationChange: Flow<Unit> = configurationRepository.onAnyConfigurationChange - - /** Represents the current state of the KeyguardRootView visibility */ - val keyguardRootViewVisibilityState: Flow<KeyguardRootViewVisibilityState> = - repository.keyguardRootViewVisibility + val configurationChange: Flow<Unit> = + configurationRepository.onAnyConfigurationChange.onStart { emit(Unit) } /** The position of the keyguard clock. */ val clockPosition: Flow<Position> = repository.clockPosition @@ -235,12 +229,17 @@ constructor( R.dimen.keyguard_translate_distance_on_swipe_up ) shadeRepository.shadeModel.map { - // On swipe up, translate the keyguard to reveal the bouncer - MathUtils.lerp( - translationDistance, - 0, - Interpolators.FAST_OUT_LINEAR_IN.getInterpolation(it.expansionAmount) - ) + if (it.expansionAmount == 0f) { + // Reset the translation value + 0f + } else { + // On swipe up, translate the keyguard to reveal the bouncer + MathUtils.lerp( + translationDistance, + 0, + Interpolators.FAST_OUT_LINEAR_IN.getInterpolation(it.expansionAmount) + ) + } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt index ac4ad39a38a5..c72e6ce0b7d6 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/KeyguardRootViewBinder.kt @@ -20,21 +20,24 @@ import android.annotation.DrawableRes import android.view.View import android.view.View.OnLayoutChangeListener import android.view.ViewGroup +import android.view.ViewGroup.OnHierarchyChangeListener import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle -import com.android.app.animation.Interpolators +import com.android.internal.jank.InteractionJankMonitor +import com.android.internal.jank.InteractionJankMonitor.CUJ_SCREEN_OFF_SHOW_AOD +import com.android.keyguard.KeyguardClockSwitch.MISSING_CLOCK_ID import com.android.systemui.common.shared.model.Icon import com.android.systemui.common.shared.model.Text import com.android.systemui.common.shared.model.TintedIcon import com.android.systemui.flags.FeatureFlags import com.android.systemui.flags.Flags +import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.ui.viewmodel.KeyguardRootViewModel import com.android.systemui.keyguard.ui.viewmodel.OccludingAppDeviceEntryMessageViewModel import com.android.systemui.lifecycle.repeatWhenAttached import com.android.systemui.plugins.ClockController import com.android.systemui.res.R import com.android.systemui.shade.domain.interactor.ShadeInteractor -import com.android.systemui.statusbar.StatusBarState import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.temporarydisplay.ViewPriority import com.android.systemui.temporarydisplay.chipbar.ChipbarCoordinator @@ -48,8 +51,6 @@ import kotlinx.coroutines.launch @ExperimentalCoroutinesApi object KeyguardRootViewBinder { - private var onLayoutChangeListener: OnLayoutChange? = null - @JvmStatic fun bind( view: ViewGroup, @@ -60,7 +61,14 @@ object KeyguardRootViewBinder { keyguardStateController: KeyguardStateController, shadeInteractor: ShadeInteractor, clockControllerProvider: Provider<ClockController>?, + interactionJankMonitor: InteractionJankMonitor?, ): DisposableHandle { + var onLayoutChangeListener: OnLayoutChange? = null + val childViews = mutableMapOf<Int, View?>() + val statusViewId = R.id.keyguard_status_view + val burnInLayerId = R.id.burn_in_layer + val aodNotificationIconContainerId = R.id.aod_notification_icon_container + val largeClockId = R.id.lockscreen_clock_view_large val disposableHandle = view.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) { @@ -86,36 +94,74 @@ object KeyguardRootViewBinder { if (featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) { launch { + viewModel.burnInLayerVisibility.collect { visibility -> + childViews[burnInLayerId]?.visibility = visibility + // Reset alpha only for the icons, as they currently have their + // own animator + childViews[aodNotificationIconContainerId]?.alpha = 0f + } + } + + launch { + viewModel.burnInLayerAlpha.collect { alpha -> + childViews[statusViewId]?.alpha = alpha + childViews[aodNotificationIconContainerId]?.alpha = alpha + } + } + + launch { + viewModel.lockscreenStateAlpha.collect { alpha -> + childViews[statusViewId]?.alpha = alpha + } + } + + launch { viewModel.translationY.collect { y -> - val burnInLayer = view.requireViewById<View>(R.id.burn_in_layer) - burnInLayer.translationY = y + childViews[burnInLayerId]?.translationY = y } } - } - if (featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) { launch { viewModel.translationX.collect { x -> - val burnInLayer = view.requireViewById<View>(R.id.burn_in_layer) - burnInLayer.translationX = x + childViews[burnInLayerId]?.translationX = x } } - } - if (featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) { launch { viewModel.scale.collect { (scale, scaleClockOnly) -> if (scaleClockOnly) { - val largeClock = - view.findViewById<View?>(R.id.lockscreen_clock_view_large) - largeClock?.let { + childViews[largeClockId]?.let { it.scaleX = scale it.scaleY = scale } } else { - val burnInLayer = view.requireViewById<View>(R.id.burn_in_layer) - burnInLayer.scaleX = scale - burnInLayer.scaleY = scale + childViews[burnInLayerId]?.scaleX = scale + childViews[burnInLayerId]?.scaleY = scale + } + } + } + + interactionJankMonitor?.let { jankMonitor -> + launch { + viewModel.goneToAodTransition.collect { + when (it.transitionState) { + TransitionState.STARTED -> { + val clockId = + clockControllerProvider?.get()?.config?.id + ?: MISSING_CLOCK_ID + val builder = + InteractionJankMonitor.Configuration.Builder + .withView(CUJ_SCREEN_OFF_SHOW_AOD, view) + .setTag(clockId) + + jankMonitor.begin(builder) + } + TransitionState.CANCELED -> + jankMonitor.cancel(CUJ_SCREEN_OFF_SHOW_AOD) + TransitionState.FINISHED -> + jankMonitor.end(CUJ_SCREEN_OFF_SHOW_AOD) + TransitionState.RUNNING -> Unit + } } } } @@ -132,54 +178,32 @@ object KeyguardRootViewBinder { } } } - - repeatOnLifecycle(Lifecycle.State.STARTED) { - if (featureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) { - launch { - viewModel.keyguardRootViewVisibilityState.collect { visibilityState -> - view.animate().cancel() - val goingToFullShade = visibilityState.goingToFullShade - val statusBarState = visibilityState.statusBarState - val isOcclusionTransitionRunning = - visibilityState.occlusionTransitionRunning - if (goingToFullShade) { - view - .animate() - .alpha(0f) - .setStartDelay( - keyguardStateController.keyguardFadingAwayDelay - ) - .setDuration( - keyguardStateController.shortenedFadingAwayDuration - ) - .setInterpolator(Interpolators.ALPHA_OUT) - .withEndAction { view.visibility = View.GONE } - .start() - } else if ( - statusBarState == StatusBarState.KEYGUARD || - statusBarState == StatusBarState.SHADE_LOCKED - ) { - view.visibility = View.VISIBLE - if (!isOcclusionTransitionRunning) { - view.alpha = 1f - } - } else { - view.visibility = View.GONE - } - } - } - } - } } viewModel.clockControllerProvider = clockControllerProvider onLayoutChangeListener = OnLayoutChange(viewModel) view.addOnLayoutChangeListener(onLayoutChangeListener) + // Views will be added or removed after the call to bind(). This is needed to avoid many + // calls to findViewById + view.setOnHierarchyChangeListener( + object : OnHierarchyChangeListener { + override fun onChildViewAdded(parent: View, child: View) { + childViews.put(child.id, view) + } + + override fun onChildViewRemoved(parent: View, child: View) { + childViews.remove(child.id) + } + } + ) + return object : DisposableHandle { override fun dispose() { disposableHandle.dispose() view.removeOnLayoutChangeListener(onLayoutChangeListener) + view.setOnHierarchyChangeListener(null) + childViews.clear() } } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/PreviewKeyguardBlueprintViewBinder.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/PreviewKeyguardBlueprintViewBinder.kt index f3586bae1a9e..2feaa2e81c0f 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/PreviewKeyguardBlueprintViewBinder.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/binder/PreviewKeyguardBlueprintViewBinder.kt @@ -24,6 +24,7 @@ import androidx.lifecycle.Lifecycle import androidx.lifecycle.repeatOnLifecycle import com.android.systemui.keyguard.ui.viewmodel.KeyguardBlueprintViewModel import com.android.systemui.lifecycle.repeatWhenAttached +import kotlinx.coroutines.DisposableHandle import kotlinx.coroutines.launch /** @@ -46,8 +47,8 @@ class PreviewKeyguardBlueprintViewBinder { constraintLayout: ConstraintLayout, viewModel: KeyguardBlueprintViewModel, finishedAddViewCallback: () -> Unit - ) { - constraintLayout.repeatWhenAttached { + ): DisposableHandle { + return constraintLayout.repeatWhenAttached { repeatOnLifecycle(Lifecycle.State.CREATED) { launch { viewModel.blueprint.collect { blueprint -> diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt index 4a2954dc6559..c1c29c416902 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/preview/KeyguardPreviewRenderer.kt @@ -322,7 +322,7 @@ constructor( @OptIn(ExperimentalCoroutinesApi::class) private fun setupKeyguardRootView(previewContext: Context, rootView: FrameLayout) { - val keyguardRootView = KeyguardRootView(previewContext, null).apply { removeAllViews() } + val keyguardRootView = KeyguardRootView(previewContext, null) disposables.add( KeyguardRootViewBinder.bind( keyguardRootView, @@ -333,6 +333,7 @@ constructor( keyguardStateController, shadeInteractor, null, // clock provider only needed for burn in + null, // jank monitor not required for preview mode ) ) rootView.addView( @@ -342,26 +343,29 @@ constructor( FrameLayout.LayoutParams.MATCH_PARENT, ), ) - PreviewKeyguardBlueprintViewBinder.bind(keyguardRootView, keyguardBlueprintViewModel) { - if (featureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) { - setupShortcuts(keyguardRootView) - } - setUpUdfps(previewContext, rootView) - - if (!shouldHideClock) { - setUpClock(previewContext, rootView) - KeyguardPreviewClockViewBinder.bind( - largeClockHostView, - smallClockHostView, - clockViewModel, - ) - } - setUpSmartspace(previewContext, rootView) - smartSpaceView?.let { - KeyguardPreviewSmartspaceViewBinder.bind(it, smartspaceViewModel) + disposables.add( + PreviewKeyguardBlueprintViewBinder.bind(keyguardRootView, keyguardBlueprintViewModel) { + if (featureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) { + setupShortcuts(keyguardRootView) + } + setUpUdfps(previewContext, rootView) + + if (!shouldHideClock) { + setUpClock(previewContext, rootView) + KeyguardPreviewClockViewBinder.bind( + largeClockHostView, + smallClockHostView, + clockViewModel, + ) + } + + setUpSmartspace(previewContext, rootView) + smartSpaceView?.let { + KeyguardPreviewSmartspaceViewBinder.bind(it, smartspaceViewModel) + } } - } + ) } private fun setupShortcuts(keyguardRootView: ConstraintLayout) { diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt new file mode 100644 index 000000000000..024707ad2885 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt @@ -0,0 +1,50 @@ +/* + * 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.systemui.keyguard.ui.viewmodel + +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.keyguard.domain.interactor.FromAodTransitionInteractor.Companion.TO_LOCKSCREEN_DURATION +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow +import javax.inject.Inject +import kotlin.time.Duration.Companion.milliseconds +import kotlinx.coroutines.flow.Flow + +/** + * Breaks down AOD->LOCKSCREEN transition into discrete steps for corresponding views to consume. + */ +@SysUISingleton +class AodToLockscreenTransitionViewModel +@Inject +constructor( + private val interactor: KeyguardTransitionInteractor, +) { + + private val transitionAnimation = + KeyguardTransitionAnimationFlow( + transitionDuration = TO_LOCKSCREEN_DURATION, + transitionFlow = interactor.aodToLockscreenTransition, + ) + + /** Ensure alpha is set to be visible */ + val lockscreenAlpha: Flow<Float> = + transitionAnimation.createFlow( + duration = 500.milliseconds, + onStart = { 1f }, + onStep = { 1f }, + ) +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt new file mode 100644 index 000000000000..601dbccb1de1 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModel.kt @@ -0,0 +1,63 @@ +/* + * 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.systemui.keyguard.ui.viewmodel + +import com.android.app.animation.Interpolators.EMPHASIZED_DECELERATE +import com.android.systemui.dagger.SysUISingleton +import com.android.systemui.keyguard.domain.interactor.FromGoneTransitionInteractor.Companion.TO_AOD_DURATION +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow +import javax.inject.Inject +import kotlin.time.Duration.Companion.milliseconds +import kotlinx.coroutines.flow.Flow + +/** Breaks down GONE->AOD transition into discrete steps for corresponding views to consume. */ +@SysUISingleton +class GoneToAodTransitionViewModel +@Inject +constructor( + private val interactor: KeyguardTransitionInteractor, +) { + + private val transitionAnimation = + KeyguardTransitionAnimationFlow( + transitionDuration = TO_AOD_DURATION, + transitionFlow = interactor.goneToAodTransition, + ) + + /** y-translation from the top of the screen for AOD */ + fun enterFromTopTranslationY(translatePx: Int): Flow<Float> { + return transitionAnimation.createFlow( + startTime = 600.milliseconds, + duration = 500.milliseconds, + onStart = { translatePx }, + onStep = { translatePx + it * -translatePx }, + onFinish = { 0f }, + onCancel = { 0f }, + interpolator = EMPHASIZED_DECELERATE, + ) + } + + /** alpha animation upon entering AOD */ + val enterFromTopAnimationAlpha: Flow<Float> = + transitionAnimation.createFlow( + startTime = 600.milliseconds, + duration = 500.milliseconds, + onStart = { 0f }, + onStep = { it }, + ) +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt index 89835fecd95c..1f98082c4065 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModel.kt @@ -17,14 +17,19 @@ package com.android.systemui.keyguard.ui.viewmodel +import android.content.Context import android.util.MathUtils +import android.view.View.VISIBLE import com.android.app.animation.Interpolators import com.android.systemui.common.shared.model.SharedNotificationContainerPosition import com.android.systemui.keyguard.domain.interactor.BurnInInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.BurnInModel -import com.android.systemui.keyguard.shared.model.KeyguardRootViewVisibilityState +import com.android.systemui.keyguard.shared.model.KeyguardState.AOD +import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.plugins.ClockController +import com.android.systemui.res.R import javax.inject.Inject import javax.inject.Provider import kotlinx.coroutines.ExperimentalCoroutinesApi @@ -32,17 +37,23 @@ import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.filter import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.merge +import kotlinx.coroutines.flow.onStart @OptIn(ExperimentalCoroutinesApi::class) class KeyguardRootViewModel @Inject constructor( + private val context: Context, private val keyguardInteractor: KeyguardInteractor, private val burnInInteractor: BurnInInteractor, + private val goneToAodTransitionViewModel: GoneToAodTransitionViewModel, + private val aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel, + private val keyguardTransitionInteractor: KeyguardTransitionInteractor, ) { data class PreviewMode(val isInPreviewMode: Boolean = false) @@ -56,9 +67,12 @@ constructor( public var clockControllerProvider: Provider<ClockController>? = null - /** Represents the current state of the KeyguardRootView visibility */ - val keyguardRootViewVisibilityState: Flow<KeyguardRootViewVisibilityState> = - keyguardInteractor.keyguardRootViewVisibilityState + val burnInLayerVisibility: Flow<Int> = + keyguardTransitionInteractor.startedKeyguardState + .filter { it == AOD || it == LOCKSCREEN } + .map { VISIBLE } + + val goneToAodTransition = keyguardTransitionInteractor.goneToAodTransition /** An observable for the alpha level for the entire keyguard root view. */ val alpha: Flow<Float> = @@ -70,9 +84,14 @@ constructor( } } - private val burnIn: Flow<BurnInModel> = - combine(keyguardInteractor.dozeAmount, burnInInteractor.keyguardBurnIn) { dozeAmount, burnIn - -> + private fun burnIn(): Flow<BurnInModel> { + val dozingAmount: Flow<Float> = + merge( + keyguardTransitionInteractor.goneToAodTransition.map { it.value }, + keyguardTransitionInteractor.dozeAmountTransition.map { it.value }, + ) + + return combine(dozingAmount, burnInInteractor.keyguardBurnIn) { dozeAmount, burnIn -> val interpolation = Interpolators.FAST_OUT_SLOW_IN.getInterpolation(dozeAmount) val useScaleOnly = clockControllerProvider?.get()?.config?.useAlternateSmartspaceAODTransition ?: false @@ -91,13 +110,61 @@ constructor( ) } } + } + + /** Specific alpha value for elements visible during [KeyguardState.LOCKSCREEN] */ + val lockscreenStateAlpha: Flow<Float> = aodToLockscreenTransitionViewModel.lockscreenAlpha + + /** For elements that appear and move during the animation -> AOD */ + val burnInLayerAlpha: Flow<Float> = + previewMode.flatMapLatest { + if (it.isInPreviewMode) { + flowOf(1f) + } else { + goneToAodTransitionViewModel.enterFromTopAnimationAlpha + } + } val translationY: Flow<Float> = - merge(keyguardInteractor.keyguardTranslationY, burnIn.map { it.translationY.toFloat() }) + previewMode.flatMapLatest { + if (it.isInPreviewMode) { + flowOf(0f) + } else { + keyguardInteractor.configurationChange.flatMapLatest { _ -> + val enterFromTopAmount = + context.resources.getDimensionPixelSize( + R.dimen.keyguard_enter_from_top_translation_y + ) + combine( + keyguardInteractor.keyguardTranslationY.onStart { emit(0f) }, + burnIn().map { it.translationY.toFloat() }.onStart { emit(0f) }, + goneToAodTransitionViewModel + .enterFromTopTranslationY(enterFromTopAmount) + .onStart { emit(0f) }, + ) { keyguardTransitionY, burnInTranslationY, goneToAodTransitionTranslationY -> + // All 3 values need to be combined for a smooth translation + keyguardTransitionY + burnInTranslationY + goneToAodTransitionTranslationY + } + } + } + } - val translationX: Flow<Float> = burnIn.map { it.translationX.toFloat() } + val translationX: Flow<Float> = + previewMode.flatMapLatest { + if (it.isInPreviewMode) { + flowOf(0f) + } else { + burnIn().map { it.translationX.toFloat() } + } + } - val scale: Flow<Pair<Float, Boolean>> = burnIn.map { Pair(it.scale, it.scaleClockOnly) } + val scale: Flow<Pair<Float, Boolean>> = + previewMode.flatMapLatest { previewMode -> + burnIn().map { + val scale = if (previewMode.isInPreviewMode) 1f else it.scale + Pair(scale, it.scaleClockOnly) + } + } /** * Puts this view-model in "preview mode", which means it's being used for UI that is rendering @@ -105,11 +172,14 @@ constructor( * lock screen. */ fun enablePreviewMode() { - val newPreviewMode = PreviewMode(true) - previewMode.value = newPreviewMode + previewMode.value = PreviewMode(true) } fun onSharedNotificationContainerPositionChanged(top: Float, bottom: Float) { + // Notifications should not be visible in preview mode + if (previewMode.value.isInPreviewMode) { + return + } keyguardInteractor.sharedNotificationContainerPosition.value = SharedNotificationContainerPosition(top, bottom) } diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java index 51972c2d025c..8dc97c0f797c 100644 --- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java +++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java @@ -1446,9 +1446,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump mBarState); } - if (mFeatureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) { - setKeyguardVisibility(mBarState, false); - } else { + if (!mFeatureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) { setKeyguardBottomAreaVisibility(mBarState, false); } @@ -2358,14 +2356,6 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump } } - private void setKeyguardVisibility(int statusBarState, boolean goingToFullShade) { - mKeyguardInteractor.setKeyguardRootVisibility( - statusBarState, - goingToFullShade, - mIsOcclusionTransitionRunning - ); - } - @Deprecated private void setKeyguardBottomAreaVisibility(int statusBarState, boolean goingToFullShade) { mKeyguardBottomArea.animate().cancel(); @@ -4443,11 +4433,13 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump && statusBarState == KEYGUARD) { // This means we're doing the screen off animation - position the keyguard status // view where it'll be on AOD, so we can animate it in. - mKeyguardStatusViewController.updatePosition( - mClockPositionResult.clockX, - mClockPositionResult.clockYFullyDozing, - mClockPositionResult.clockScale, - false /* animate */); + if (!mFeatureFlags.isEnabled(Flags.MIGRATE_NSSL)) { + mKeyguardStatusViewController.updatePosition( + mClockPositionResult.clockX, + mClockPositionResult.clockYFullyDozing, + mClockPositionResult.clockScale, + false /* animate */); + } } mKeyguardStatusViewController.setKeyguardStatusViewVisibility( @@ -4456,9 +4448,7 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump goingToFullShade, mBarState); - if (mFeatureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) { - setKeyguardVisibility(statusBarState, goingToFullShade); - } else { + if (!mFeatureFlags.isEnabled(Flags.MIGRATE_SPLIT_KEYGUARD_BOTTOM_AREA)) { setKeyguardBottomAreaVisibility(statusBarState, goingToFullShade); } @@ -4562,7 +4552,12 @@ public final class NotificationPanelViewController implements ShadeSurface, Dump public void showAodUi() { setDozing(true /* dozing */, false /* animate */); mStatusBarStateController.setUpcomingState(KEYGUARD); - mStatusBarStateListener.onStateChanged(KEYGUARD); + + if (mFeatureFlags.isEnabled(Flags.MIGRATE_NSSL)) { + mStatusBarStateController.setState(KEYGUARD); + } else { + mStatusBarStateListener.onStateChanged(KEYGUARD); + } mStatusBarStateListener.onDozeAmountChanged(1f, 1f); setExpandedFraction(1f); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt index 2c15e27b8148..de37170b1f7d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt @@ -34,6 +34,8 @@ import com.android.systemui.statusbar.policy.KeyguardStateController import com.android.systemui.util.TraceUtils import com.android.systemui.util.settings.GlobalSettings import javax.inject.Inject +import com.android.systemui.flags.FeatureFlags +import com.android.systemui.flags.Flags /** * When to show the keyguard (AOD) view. This should be once the light reveal scrim is barely @@ -65,7 +67,8 @@ class UnlockedScreenOffAnimationController @Inject constructor( private val notifShadeWindowControllerLazy: dagger.Lazy<NotificationShadeWindowController>, private val interactionJankMonitor: InteractionJankMonitor, private val powerManager: PowerManager, - private val handler: Handler = Handler() + private val handler: Handler = Handler(), + private val featureFlags: FeatureFlags, ) : WakefulnessLifecycle.Observer, ScreenOffAnimation { private lateinit var centralSurfaces: CentralSurfaces private lateinit var shadeViewController: ShadeViewController @@ -285,7 +288,11 @@ class UnlockedScreenOffAnimationController @Inject constructor( // up, with unpredictable consequences. if (!powerManager.isInteractive(Display.DEFAULT_DISPLAY) && shouldAnimateInKeyguard) { - aodUiAnimationPlaying = true + if (!featureFlags.isEnabled(Flags.MIGRATE_KEYGUARD_STATUS_VIEW)) { + // Tracking this state should no longer be relevant, as the isInteractive + // check covers it + aodUiAnimationPlaying = true + } // Show AOD. That'll cause the KeyguardVisibilityHelper to call // #animateInKeyguard. diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java index 62e238164514..b614b6d0547d 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchController.java @@ -38,6 +38,7 @@ import com.android.settingslib.drawable.CircleFramedDrawable; import com.android.systemui.res.R; import com.android.systemui.animation.Expandable; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.flags.FeatureFlags; import com.android.systemui.plugins.FalsingManager; import com.android.systemui.plugins.statusbar.StatusBarStateController; import com.android.systemui.qs.user.UserSwitchDialogController; @@ -148,6 +149,7 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout> DozeParameters dozeParameters, ScreenOffAnimationController screenOffAnimationController, UserSwitchDialogController userSwitchDialogController, + FeatureFlags featureFlags, UiEventLogger uiEventLogger) { super(view); if (DEBUG) Log.d(TAG, "New KeyguardQsUserSwitchController"); @@ -160,7 +162,8 @@ public class KeyguardQsUserSwitchController extends ViewController<FrameLayout> mStatusBarStateController = statusBarStateController; mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController, dozeParameters, - screenOffAnimationController, /* animateYPos= */ false, /* logBuffer= */ null); + screenOffAnimationController, /* animateYPos= */ false, + featureFlags, /* logBuffer= */ null); mUserSwitchDialogController = userSwitchDialogController; mUiEventLogger = uiEventLogger; } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java index bb074ac33ddb..dfe26865f978 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherController.java @@ -38,10 +38,11 @@ import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.keyguard.KeyguardVisibilityHelper; import com.android.keyguard.dagger.KeyguardUserSwitcherScope; import com.android.settingslib.drawable.CircleFramedDrawable; -import com.android.systemui.res.R; import com.android.systemui.dagger.qualifiers.Main; +import com.android.systemui.flags.FeatureFlags; import com.android.systemui.keyguard.ScreenLifecycle; import com.android.systemui.plugins.statusbar.StatusBarStateController; +import com.android.systemui.res.R; import com.android.systemui.statusbar.SysuiStatusBarStateController; import com.android.systemui.statusbar.notification.AnimatableProperty; import com.android.systemui.statusbar.notification.PropertyAnimator; @@ -160,6 +161,7 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS KeyguardStateController keyguardStateController, SysuiStatusBarStateController statusBarStateController, KeyguardUpdateMonitor keyguardUpdateMonitor, + FeatureFlags featureFlags, DozeParameters dozeParameters, ScreenOffAnimationController screenOffAnimationController) { super(keyguardUserSwitcherView); @@ -174,7 +176,8 @@ public class KeyguardUserSwitcherController extends ViewController<KeyguardUserS mUserSwitcherController, this); mKeyguardVisibilityHelper = new KeyguardVisibilityHelper(mView, keyguardStateController, dozeParameters, - screenOffAnimationController, /* animateYPos= */ false, /* logBuffer= */ null); + screenOffAnimationController, /* animateYPos= */ false, + featureFlags, /* logBuffer= */ null); mBackground = new KeyguardUserSwitcherScrim(context); } diff --git a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt index 6afa5256523c..4d8768f5e9e0 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/keyguard/ClockEventControllerTest.kt @@ -25,9 +25,11 @@ import com.android.systemui.SysuiTestCase import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.flags.Flags import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository -import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory -import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.TransitionState +import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.log.LogBuffer import com.android.systemui.plugins.ClockAnimations import com.android.systemui.plugins.ClockController @@ -47,8 +49,8 @@ import com.android.systemui.util.mockito.mock import java.util.TimeZone import java.util.concurrent.Executor import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.runBlocking -import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.yield import org.junit.Assert.assertEquals import org.junit.Before @@ -90,10 +92,10 @@ class ClockEventControllerTest : SysuiTestCase() { @Mock private lateinit var smallClockEvents: ClockFaceEvents @Mock private lateinit var largeClockEvents: ClockFaceEvents @Mock private lateinit var parentView: View - @Mock private lateinit var transitionRepository: KeyguardTransitionRepository private lateinit var repository: FakeKeyguardRepository @Mock private lateinit var smallLogBuffer: LogBuffer @Mock private lateinit var largeLogBuffer: LogBuffer + @Mock private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor private lateinit var underTest: ClockEventController @Before @@ -125,17 +127,13 @@ class ClockEventControllerTest : SysuiTestCase() { withDeps.featureFlags.apply { set(Flags.REGION_SAMPLING, false) - set(Flags.DOZING_MIGRATION_1, false) + set(Flags.MIGRATE_KEYGUARD_STATUS_VIEW, false) set(Flags.FACE_AUTH_REFACTOR, false) } underTest = ClockEventController( withDeps.keyguardInteractor, - KeyguardTransitionInteractorFactory.create( - scope = TestScope().backgroundScope, - featureFlags = withDeps.featureFlags, - ) - .keyguardTransitionInteractor, + keyguardTransitionInteractor, broadcastDispatcher, batteryController, keyguardUpdateMonitor, @@ -316,6 +314,68 @@ class ClockEventControllerTest : SysuiTestCase() { } @Test + fun listenForDozeAmountTransition_updatesClockDozeAmount() = + runBlocking(IMMEDIATE) { + val transitionStep = MutableStateFlow(TransitionStep()) + whenever(keyguardTransitionInteractor.dozeAmountTransition).thenReturn(transitionStep) + + val job = underTest.listenForDozeAmountTransition(this) + transitionStep.value = + TransitionStep( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.AOD, + value = 0.4f + ) + yield() + + verify(animations, times(2)).doze(0.4f) + + job.cancel() + } + + @Test + fun listenForTransitionToAodFromGone_updatesClockDozeAmountToOne() = + runBlocking(IMMEDIATE) { + val transitionStep = MutableStateFlow(TransitionStep()) + whenever(keyguardTransitionInteractor.transitionStepsToState(KeyguardState.AOD)) + .thenReturn(transitionStep) + + val job = underTest.listenForAnyStateToAodTransition(this) + transitionStep.value = + TransitionStep( + from = KeyguardState.GONE, + to = KeyguardState.AOD, + transitionState = TransitionState.STARTED, + ) + yield() + + verify(animations, times(2)).doze(1f) + + job.cancel() + } + + @Test + fun listenForTransitionToAodFromLockscreen_neverUpdatesClockDozeAmount() = + runBlocking(IMMEDIATE) { + val transitionStep = MutableStateFlow(TransitionStep()) + whenever(keyguardTransitionInteractor.transitionStepsToState(KeyguardState.AOD)) + .thenReturn(transitionStep) + + val job = underTest.listenForAnyStateToAodTransition(this) + transitionStep.value = + TransitionStep( + from = KeyguardState.LOCKSCREEN, + to = KeyguardState.AOD, + transitionState = TransitionState.STARTED, + ) + yield() + + verify(animations, never()).doze(1f) + + job.cancel() + } + + @Test fun unregisterListeners_validate() = runBlocking(IMMEDIATE) { underTest.unregisterListeners() diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java index 3b8e02f7455a..22c75d85d4a1 100644 --- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewControllerBaseTest.java @@ -16,6 +16,8 @@ package com.android.keyguard; +import static kotlinx.coroutines.flow.FlowKt.emptyFlow; + import static org.mockito.Mockito.atLeast; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -31,6 +33,7 @@ import com.android.systemui.dump.DumpManager; import com.android.systemui.flags.FeatureFlags; import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository; import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory; +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor; import com.android.systemui.power.data.repository.FakePowerRepository; import com.android.systemui.power.domain.interactor.PowerInteractorFactory; import com.android.systemui.statusbar.notification.AnimatableProperty; @@ -60,6 +63,7 @@ public class KeyguardStatusViewControllerBaseTest extends SysuiTestCase { @Mock protected FeatureFlags mFeatureFlags; @Mock protected InteractionJankMonitor mInteractionJankMonitor; @Mock protected ViewTreeObserver mViewTreeObserver; + @Mock protected KeyguardTransitionInteractor mKeyguardTransitionInteractor; @Mock protected DumpManager mDumpManager; protected FakeKeyguardRepository mFakeKeyguardRepository; protected FakePowerRepository mFakePowerRepository; @@ -90,6 +94,7 @@ public class KeyguardStatusViewControllerBaseTest extends SysuiTestCase { mFeatureFlags, mInteractionJankMonitor, deps.getKeyguardInteractor(), + mKeyguardTransitionInteractor, mDumpManager, PowerInteractorFactory.create( mFakePowerRepository @@ -105,8 +110,8 @@ public class KeyguardStatusViewControllerBaseTest extends SysuiTestCase { }; when(mKeyguardStatusView.getViewTreeObserver()).thenReturn(mViewTreeObserver); - when(mKeyguardClockSwitchController.getView()).thenReturn(mKeyguardClockSwitch); + when(mKeyguardTransitionInteractor.getGoneToAodTransition()).thenReturn(emptyFlow()); } protected void givenViewAttached() { diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt new file mode 100644 index 000000000000..255f4df17244 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/GoneToAodTransitionViewModelTest.kt @@ -0,0 +1,112 @@ +/* + * 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.systemui.keyguard.ui.viewmodel + +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import com.android.systemui.SysuiTestCase +import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.TransitionState +import com.android.systemui.keyguard.shared.model.TransitionStep +import com.google.common.collect.Range +import com.google.common.truth.Truth.assertThat +import kotlinx.coroutines.test.StandardTestDispatcher +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidJUnit4::class) +class GoneToAodTransitionViewModelTest : SysuiTestCase() { + private lateinit var underTest: GoneToAodTransitionViewModel + private lateinit var repository: FakeKeyguardTransitionRepository + private lateinit var testScope: TestScope + + @Before + fun setUp() { + val testDispatcher = StandardTestDispatcher() + testScope = TestScope(testDispatcher) + + repository = FakeKeyguardTransitionRepository() + val interactor = + KeyguardTransitionInteractorFactory.create( + scope = testScope.backgroundScope, + repository = repository, + ) + .keyguardTransitionInteractor + underTest = GoneToAodTransitionViewModel(interactor) + } + + @Test + fun enterFromTopTranslationY() = + testScope.runTest { + val pixels = -100f + val enterFromTopTranslationY by + collectLastValue(underTest.enterFromTopTranslationY(pixels.toInt())) + + // The animation should only start > halfway through + repository.sendTransitionStep(step(0f, TransitionState.STARTED)) + assertThat(enterFromTopTranslationY).isEqualTo(pixels) + + repository.sendTransitionStep(step(0.5f)) + assertThat(enterFromTopTranslationY).isEqualTo(pixels) + + repository.sendTransitionStep(step(.85f)) + assertThat(enterFromTopTranslationY).isIn(Range.closed(pixels, 0f)) + + // At the end, the translation should be complete and set to zero + repository.sendTransitionStep(step(1f)) + assertThat(enterFromTopTranslationY).isEqualTo(0f) + } + + @Test + fun enterFromTopAnimationAlpha() = + testScope.runTest { + val enterFromTopAnimationAlpha by collectLastValue(underTest.enterFromTopAnimationAlpha) + + // The animation should only start > halfway through + repository.sendTransitionStep(step(0f, TransitionState.STARTED)) + assertThat(enterFromTopAnimationAlpha).isEqualTo(0f) + + repository.sendTransitionStep(step(0.5f)) + assertThat(enterFromTopAnimationAlpha).isEqualTo(0f) + + repository.sendTransitionStep(step(.85f)) + assertThat(enterFromTopAnimationAlpha).isIn(Range.closed(0f, 1f)) + + repository.sendTransitionStep(step(1f)) + assertThat(enterFromTopAnimationAlpha).isEqualTo(1f) + } + + private fun step( + value: Float, + state: TransitionState = TransitionState.RUNNING + ): TransitionStep { + return TransitionStep( + from = KeyguardState.GONE, + to = KeyguardState.AOD, + value = value, + transitionState = state, + ownerName = "GoneToAodTransitionViewModelTest" + ) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt index 71688db76a8b..4f545cb0e288 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/KeyguardRootViewModelTest.kt @@ -17,8 +17,10 @@ package com.android.systemui.keyguard.ui.viewmodel +import android.view.View import androidx.test.filters.SmallTest import com.android.systemui.SysuiTestCase +import com.android.systemui.common.ui.data.repository.FakeConfigurationRepository import com.android.systemui.coroutines.collectLastValue import com.android.systemui.flags.FakeFeatureFlags import com.android.systemui.flags.Flags @@ -26,12 +28,17 @@ import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository import com.android.systemui.keyguard.domain.interactor.BurnInInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardInteractorFactory +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor import com.android.systemui.keyguard.shared.model.BurnInModel +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.plugins.ClockController import com.android.systemui.util.mockito.whenever import com.google.common.truth.Truth.assertThat import javax.inject.Provider +import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.test.StandardTestDispatcher import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest @@ -41,6 +48,7 @@ import org.junit.runner.RunWith import org.junit.runners.JUnit4 import org.mockito.Answers import org.mockito.Mock +import org.mockito.Mockito.anyInt import org.mockito.MockitoAnnotations @SmallTest @@ -51,10 +59,20 @@ class KeyguardRootViewModelTest : SysuiTestCase() { private lateinit var testScope: TestScope private lateinit var repository: FakeKeyguardRepository private lateinit var keyguardInteractor: KeyguardInteractor + private lateinit var configurationRepository: FakeConfigurationRepository @Mock private lateinit var burnInInteractor: BurnInInteractor + @Mock private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor + @Mock private lateinit var goneToAodTransitionViewModel: GoneToAodTransitionViewModel + @Mock + private lateinit var aodToLockscreenTransitionViewModel: AodToLockscreenTransitionViewModel @Mock(answer = Answers.RETURNS_DEEP_STUBS) private lateinit var clockController: ClockController private val burnInFlow = MutableStateFlow(BurnInModel()) + private val goneToAodTransitionViewModelVisibility = MutableStateFlow(0) + private val enterFromTopAnimationAlpha = MutableStateFlow(0f) + private val goneToAodTransitionStep = MutableSharedFlow<TransitionStep>(replay = 1) + private val dozeAmountTransitionStep = MutableSharedFlow<TransitionStep>(replay = 1) + private val startedKeyguardState = MutableStateFlow(KeyguardState.GONE) @Before fun setUp() { @@ -71,9 +89,30 @@ class KeyguardRootViewModelTest : SysuiTestCase() { val withDeps = KeyguardInteractorFactory.create(featureFlags = featureFlags) keyguardInteractor = withDeps.keyguardInteractor repository = withDeps.repository + configurationRepository = withDeps.configurationRepository + + whenever(goneToAodTransitionViewModel.enterFromTopTranslationY(anyInt())) + .thenReturn(emptyFlow<Float>()) + whenever(goneToAodTransitionViewModel.enterFromTopAnimationAlpha) + .thenReturn(enterFromTopAnimationAlpha) whenever(burnInInteractor.keyguardBurnIn).thenReturn(burnInFlow) - underTest = KeyguardRootViewModel(keyguardInteractor, burnInInteractor) + + whenever(keyguardTransitionInteractor.goneToAodTransition) + .thenReturn(goneToAodTransitionStep) + whenever(keyguardTransitionInteractor.dozeAmountTransition) + .thenReturn(dozeAmountTransitionStep) + whenever(keyguardTransitionInteractor.startedKeyguardState).thenReturn(startedKeyguardState) + + underTest = + KeyguardRootViewModel( + context, + keyguardInteractor, + burnInInteractor, + goneToAodTransitionViewModel, + aodToLockscreenTransitionViewModel, + keyguardTransitionInteractor, + ) underTest.clockControllerProvider = Provider { clockController } } @@ -118,7 +157,7 @@ class KeyguardRootViewModelTest : SysuiTestCase() { val scale by collectLastValue(underTest.scale) // Set to not dozing (on lockscreen) - repository.setDozeAmount(0f) + dozeAmountTransitionStep.emit(TransitionStep(value = 0f)) // Trigger a change to the burn-in model burnInFlow.value = @@ -141,8 +180,7 @@ class KeyguardRootViewModelTest : SysuiTestCase() { val scale by collectLastValue(underTest.scale) // Set to dozing (on AOD) - repository.setDozeAmount(1f) - + dozeAmountTransitionStep.emit(TransitionStep(value = 1f)) // Trigger a change to the burn-in model burnInFlow.value = BurnInModel( @@ -150,10 +188,15 @@ class KeyguardRootViewModelTest : SysuiTestCase() { translationY = 30, scale = 0.5f, ) - assertThat(translationX).isEqualTo(20) assertThat(translationY).isEqualTo(30) assertThat(scale).isEqualTo(Pair(0.5f, true /* scaleClockOnly */)) + + // Set to the beginning of GONE->AOD transition + goneToAodTransitionStep.emit(TransitionStep(value = 0f)) + assertThat(translationX).isEqualTo(0) + assertThat(translationY).isEqualTo(0) + assertThat(scale).isEqualTo(Pair(1f, true /* scaleClockOnly */)) } @Test @@ -166,7 +209,7 @@ class KeyguardRootViewModelTest : SysuiTestCase() { val scale by collectLastValue(underTest.scale) // Set to dozing (on AOD) - repository.setDozeAmount(1f) + dozeAmountTransitionStep.emit(TransitionStep(value = 1f)) // Trigger a change to the burn-in model burnInFlow.value = @@ -180,4 +223,28 @@ class KeyguardRootViewModelTest : SysuiTestCase() { assertThat(translationY).isEqualTo(0) assertThat(scale).isEqualTo(Pair(0.5f, false /* scaleClockOnly */)) } + + @Test + fun burnInLayerVisibility() = + testScope.runTest { + val burnInLayerVisibility by collectLastValue(underTest.burnInLayerVisibility) + + startedKeyguardState.value = KeyguardState.OCCLUDED + assertThat(burnInLayerVisibility).isNull() + + startedKeyguardState.value = KeyguardState.AOD + assertThat(burnInLayerVisibility).isEqualTo(View.VISIBLE) + } + + @Test + fun burnInLayerAlpha() = + testScope.runTest { + val burnInLayerAlpha by collectLastValue(underTest.burnInLayerAlpha) + + enterFromTopAnimationAlpha.value = 0.2f + assertThat(burnInLayerAlpha).isEqualTo(0.2f) + + enterFromTopAnimationAlpha.value = 1f + assertThat(burnInLayerAlpha).isEqualTo(1f) + } } diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java index 4f0cec5759e5..6223e250d603 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerBaseTest.java @@ -390,6 +390,7 @@ public class NotificationPanelViewControllerBaseTest extends SysuiTestCase { mFeatureFlags, mInteractionJankMonitor, mKeyguardInteractor, + mKeyguardTransitionInteractor, mDumpManager, mPowerInteractor)); diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt index e6f8c4861a94..9aafee4770de 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt @@ -16,6 +16,8 @@ package com.android.systemui.statusbar.phone +import com.android.systemui.flags.FakeFeatureFlags +import com.android.systemui.flags.Flags import android.os.Handler import android.os.PowerManager import android.testing.AndroidTestingRunner @@ -80,10 +82,14 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() { @Mock private lateinit var handler: Handler + private lateinit var featureFlags: FakeFeatureFlags + @Before fun setUp() { MockitoAnnotations.initMocks(this) - + featureFlags = FakeFeatureFlags().apply { + set(Flags.MIGRATE_KEYGUARD_STATUS_VIEW, false) + } controller = UnlockedScreenOffAnimationController( context, wakefulnessLifecycle, @@ -95,7 +101,8 @@ class UnlockedScreenOffAnimationControllerTest : SysuiTestCase() { dagger.Lazy<NotificationShadeWindowController> { notifShadeWindowController }, interactionJankMonitor, powerManager, - handler = handler + handler = handler, + featureFlags, ) controller.initialize(centralSurfaces, shadeViewController, lightRevealScrim) diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt index 1250228e2d37..d33806e131d5 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt @@ -16,6 +16,7 @@ package com.android.systemui.statusbar.policy +import com.android.systemui.flags.FakeFeatureFlags import android.testing.AndroidTestingRunner import android.testing.TestableLooper import android.testing.ViewUtils @@ -77,11 +78,13 @@ class KeyguardQsUserSwitchControllerTest : SysuiTestCase() { private lateinit var view: FrameLayout private lateinit var testableLooper: TestableLooper private lateinit var keyguardQsUserSwitchController: KeyguardQsUserSwitchController + private lateinit var featureFlags: FakeFeatureFlags @Before fun setUp() { MockitoAnnotations.initMocks(this) testableLooper = TestableLooper.get(this) + featureFlags = FakeFeatureFlags() view = LayoutInflater.from(context) .inflate(R.layout.keyguard_qs_user_switch, null) as FrameLayout @@ -98,6 +101,7 @@ class KeyguardQsUserSwitchControllerTest : SysuiTestCase() { dozeParameters, screenOffAnimationController, userSwitchDialogController, + featureFlags, uiEventLogger) ViewUtils.attachView(view) diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt b/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt index 10b284a03a59..5dcc7423ecc6 100644 --- a/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt +++ b/packages/SystemUI/tests/utils/src/com/android/systemui/common/ui/data/repository/FakeConfigurationRepository.kt @@ -47,7 +47,7 @@ class FakeConfigurationRepository @Inject constructor() : ConfigurationRepositor } override fun getDimensionPixelSize(id: Int): Int { - throw IllegalStateException("Don't use for tests") + return 0 } } |