Merge "Revert^2 "Prevent notif flicker during entirety of swipe to unlock"" into main
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelTest.kt
index e7aaddd..857b9f8 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGoneTransitionViewModelTest.kt
@@ -68,9 +68,7 @@
repository.sendTransitionStep(step(0f))
assertThat(alpha).isEqualTo(0.5f)
- repository.sendTransitionStep(step(0.25f))
- assertThat(alpha).isEqualTo(0.25f)
-
+ // Before the halfway point, it will have reached zero
repository.sendTransitionStep(step(.5f))
assertThat(alpha).isEqualTo(0f)
}
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
index 53a8e5d..5256bb9 100644
--- a/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
+++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModelTest.kt
@@ -720,6 +720,59 @@
}
@Test
+ fun alphaDoesNotUpdateWhileGoneTransitionIsRunning() =
+ testScope.runTest {
+ val viewState = ViewStateAccessor()
+ val alpha by collectLastValue(underTest.keyguardAlpha(viewState))
+
+ showLockscreen()
+ // GONE transition gets to 90% complete
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GONE,
+ transitionState = TransitionState.STARTED,
+ value = 0f,
+ )
+ )
+ runCurrent()
+ keyguardTransitionRepository.sendTransitionStep(
+ TransitionStep(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GONE,
+ transitionState = TransitionState.RUNNING,
+ value = 0.9f,
+ )
+ )
+ runCurrent()
+
+ // At this point, alpha should be zero
+ assertThat(alpha).isEqualTo(0f)
+
+ // An attempt to override by the shade should be ignored
+ shadeRepository.setQsExpansion(0.5f)
+ assertThat(alpha).isEqualTo(0f)
+ }
+
+ @Test
+ fun alphaWhenGoneIsSetToOne() =
+ testScope.runTest {
+ val viewState = ViewStateAccessor()
+ val alpha by collectLastValue(underTest.keyguardAlpha(viewState))
+
+ showLockscreen()
+
+ keyguardTransitionRepository.sendTransitionSteps(
+ from = KeyguardState.LOCKSCREEN,
+ to = KeyguardState.GONE,
+ testScope
+ )
+ keyguardRepository.setStatusBarState(StatusBarState.SHADE)
+
+ assertThat(alpha).isEqualTo(1f)
+ }
+
+ @Test
fun shadeCollapseFadeIn() =
testScope.runTest {
val fadeIn by collectValues(underTest.shadeCollapseFadeIn)
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 12b27eb..2649d43 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
@@ -289,7 +289,10 @@
.collect { pair ->
val (isKeyguardGoingAway, lastStartedStep) = pair
if (isKeyguardGoingAway && lastStartedStep.to == KeyguardState.LOCKSCREEN) {
- startTransitionTo(KeyguardState.GONE)
+ startTransitionTo(
+ KeyguardState.GONE,
+ modeOnCanceled = TransitionModeOnCanceled.RESET,
+ )
}
}
}
@@ -303,20 +306,6 @@
startTransitionTo(KeyguardState.GONE)
}
}
-
- return
- }
-
- scope.launch {
- keyguardInteractor.isKeyguardGoingAway
- .sample(startedKeyguardTransitionStep, ::Pair)
- .collect { pair ->
- KeyguardWmStateRefactor.assertInLegacyMode()
- val (isKeyguardGoingAway, lastStartedStep) = pair
- if (isKeyguardGoingAway && lastStartedStep.to == KeyguardState.LOCKSCREEN) {
- startTransitionTo(KeyguardState.GONE)
- }
- }
}
}
@@ -413,7 +402,7 @@
val TO_OCCLUDED_DURATION = 450.milliseconds
val TO_AOD_DURATION = 500.milliseconds
val TO_PRIMARY_BOUNCER_DURATION = DEFAULT_DURATION
- val TO_GONE_DURATION = DEFAULT_DURATION
+ val TO_GONE_DURATION = 633.milliseconds
val TO_GLANCEABLE_HUB_DURATION = 1.seconds
}
}
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
index c409028..cbbb820 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AodToLockscreenTransitionViewModel.kt
@@ -30,8 +30,6 @@
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.map
/**
* Breaks down AOD->LOCKSCREEN transition into discrete steps for corresponding views to consume.
@@ -53,6 +51,8 @@
to = KeyguardState.LOCKSCREEN,
)
+ private var isShadeExpanded = false
+
/**
* Begin the transition from wherever the y-translation value is currently. This helps ensure a
* smooth transition if a transition in canceled.
@@ -77,22 +77,21 @@
}
val notificationAlpha: Flow<Float> =
- combine(
- shadeInteractor.shadeExpansion.map { it > 0f },
- shadeInteractor.qsExpansion.map { it > 0f },
- transitionAnimation.sharedFlow(
- duration = 500.milliseconds,
- onStep = { it },
- onCancel = { 1f },
- ),
- ) { isShadeExpanded, isQsExpanded, alpha ->
- if (isShadeExpanded || isQsExpanded) {
- // One example of this happening is dragging a notification while pulsing on AOD
- 1f
- } else {
- alpha
- }
- }
+ transitionAnimation.sharedFlow(
+ duration = 500.milliseconds,
+ onStart = {
+ isShadeExpanded =
+ shadeInteractor.shadeExpansion.value > 0f ||
+ shadeInteractor.qsExpansion.value > 0f
+ },
+ onStep = {
+ if (isShadeExpanded) {
+ 1f
+ } else {
+ it
+ }
+ },
+ )
val shortcutsAlpha: Flow<Float> =
transitionAnimation.sharedFlow(
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
index bc60c83..cde45f2 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractor.kt
@@ -66,7 +66,7 @@
val isAnyExpanded: StateFlow<Boolean>
/** The amount [0-1] that the shade has been opened. */
- val shadeExpansion: Flow<Float>
+ val shadeExpansion: StateFlow<Float>
/**
* The amount [0-1] QS has been opened. Normal shade with notifications (QQS) visible will
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt
index e9bb4c6..5fbd2cf 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorEmptyImpl.kt
@@ -29,7 +29,7 @@
private val inactiveFlowBoolean = MutableStateFlow(false)
private val inactiveFlowFloat = MutableStateFlow(0f)
override val isShadeEnabled: StateFlow<Boolean> = inactiveFlowBoolean
- override val shadeExpansion: Flow<Float> = inactiveFlowFloat
+ override val shadeExpansion: StateFlow<Float> = inactiveFlowFloat
override val qsExpansion: StateFlow<Float> = inactiveFlowFloat
override val isQsExpanded: StateFlow<Boolean> = inactiveFlowBoolean
override val isQsBypassingShade: Flow<Boolean> = inactiveFlowBoolean
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt
index 421a761..ac881b5 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorLegacyImpl.kt
@@ -50,7 +50,7 @@
* The amount [0-1] that the shade has been opened. Uses stateIn to avoid redundant calculations
* in downstream flows.
*/
- override val shadeExpansion: Flow<Float> =
+ override val shadeExpansion: StateFlow<Float> =
combine(
repository.lockscreenShadeExpansion,
keyguardRepository.statusBarState,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt
index 7785eda..7f35f17 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/shade/domain/interactor/ShadeInteractorSceneContainerImpl.kt
@@ -49,7 +49,9 @@
sharedNotificationContainerInteractor: SharedNotificationContainerInteractor,
shadeRepository: ShadeRepository,
) : BaseShadeInteractor {
- override val shadeExpansion: Flow<Float> = sceneBasedExpansion(sceneInteractor, Scenes.Shade)
+ override val shadeExpansion: StateFlow<Float> =
+ sceneBasedExpansion(sceneInteractor, Scenes.Shade)
+ .stateIn(scope, SharingStarted.Eagerly, 0f)
private val sceneBasedQsExpansion = sceneBasedExpansion(sceneInteractor, Scenes.QuickSettings)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
index ab6c148..d112edb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/ui/viewmodel/SharedNotificationContainerViewModel.kt
@@ -35,7 +35,7 @@
import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER
import com.android.systemui.keyguard.shared.model.StatusBarState.SHADE
import com.android.systemui.keyguard.shared.model.StatusBarState.SHADE_LOCKED
-import com.android.systemui.keyguard.shared.model.TransitionState.FINISHED
+import com.android.systemui.keyguard.shared.model.TransitionState.RUNNING
import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerToGoneTransitionViewModel
import com.android.systemui.keyguard.ui.viewmodel.AodBurnInViewModel
import com.android.systemui.keyguard.ui.viewmodel.AodToLockscreenTransitionViewModel
@@ -366,21 +366,34 @@
}
}
}
- .onStart { emit(0f) }
+ .onStart { emit(1f) }
.dumpWhileCollecting("alphaForShadeAndQsExpansion")
- private val alphaWhenGoneAndShadeState: Flow<Float> =
- combineTransform(
- keyguardTransitionInteractor.transitions
- .map { step -> step.to == GONE && step.transitionState == FINISHED }
- .distinctUntilChanged(),
- keyguardInteractor.statusBarState,
- ) { isGoneTransitionFinished, statusBarState ->
- if (isGoneTransitionFinished && statusBarState == SHADE) {
- emit(1f)
+ private val isGoneTransitionRunning: Flow<Boolean> =
+ flow {
+ while (currentCoroutineContext().isActive) {
+ emit(false)
+ // Ensure start where GONE is inactive
+ keyguardTransitionInteractor.transitionValue(GONE).first { it == 0f }
+ // Wait for a GONE transition to begin
+ keyguardTransitionInteractor.transitionStepsToState(GONE).first {
+ it.value > 0f && it.transitionState == RUNNING
+ }
+ emit(true)
+ // Now await the signal that SHADE state has been reached or the GONE transition
+ // was reversed. Until SHADE state has been replaced and merged with GONE, it is
+ // the only source of when it is considered safe to reset alpha to 1f for HUNs.
+ combine(
+ keyguardInteractor.statusBarState,
+ // Emit -1f on start to make sure the flow runs
+ keyguardTransitionInteractor.transitionValue(GONE).onStart { emit(-1f) }
+ ) { statusBarState, goneValue ->
+ statusBarState == SHADE || goneValue == 0f
+ }
+ .first { it }
}
}
- .dumpWhileCollecting("alphaWhenGoneAndShadeState")
+ .dumpWhileCollecting("goneTransitionInProgress")
fun keyguardAlpha(viewState: ViewStateAccessor): Flow<Float> {
// All transition view models are mututally exclusive, and safe to merge
@@ -407,12 +420,11 @@
return merge(
alphaTransitions,
- // Sends a final alpha value of 1f when truly gone, to make sure HUNs appear
- alphaWhenGoneAndShadeState,
// These remaining cases handle alpha changes within an existing state, such as
// shade expansion or swipe to dismiss
combineTransform(
isOnLockscreenWithoutShade,
+ isGoneTransitionRunning,
shadeCollapseFadeIn,
alphaForShadeAndQsExpansion,
keyguardInteractor.dismissAlpha.dumpWhileCollecting(
@@ -420,6 +432,7 @@
),
) {
isOnLockscreenWithoutShade,
+ isGoneTransitionRunning,
shadeCollapseFadeIn,
alphaForShadeAndQsExpansion,
dismissAlpha ->
@@ -427,7 +440,7 @@
if (!shadeCollapseFadeIn && dismissAlpha != null) {
emit(dismissAlpha)
}
- } else {
+ } else if (!isGoneTransitionRunning) {
emit(alphaForShadeAndQsExpansion)
}
},