diff options
| author | 2024-09-27 09:43:32 +0000 | |
|---|---|---|
| committer | 2024-09-27 09:43:32 +0000 | |
| commit | 32658daaec5e1345e8a65e47d8cd1487fccbb95b (patch) | |
| tree | b679ac46f7f298de42d15950f453f6e9284e3ecb | |
| parent | f21ac8b32c2e63d43d2bc99e0d764187345da7fa (diff) | |
| parent | 5783a9926d12346fe8d1eb5dcae096be6e53a2df (diff) | |
Merge "[flexiglass] Fixes issue where user management settings didn't show" into main
2 files changed, 116 insertions, 5 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt index 29035ce2aa0a..73a4bd7d1ce4 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractorTest.kt @@ -19,17 +19,22 @@ package com.android.systemui.keyguard.domain.interactor import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest +import com.android.compose.animation.scene.ObservableTransitionState import com.android.systemui.SysuiTestCase import com.android.systemui.authentication.data.repository.fakeAuthenticationRepository import com.android.systemui.authentication.shared.model.AuthenticationMethodModel import com.android.systemui.bouncer.data.repository.fakeKeyguardBouncerRepository import com.android.systemui.bouncer.domain.interactor.alternateBouncerInteractor import com.android.systemui.coroutines.collectLastValue +import com.android.systemui.deviceentry.data.repository.fakeDeviceEntryRepository +import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor import com.android.systemui.deviceentry.domain.interactor.deviceUnlockedInteractor import com.android.systemui.flags.EnableSceneContainer +import com.android.systemui.keyguard.data.repository.fakeDeviceEntryFingerprintAuthRepository import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository import com.android.systemui.keyguard.shared.model.DismissAction import com.android.systemui.keyguard.shared.model.KeyguardDone +import com.android.systemui.keyguard.shared.model.SuccessFingerprintAuthenticationStatus import com.android.systemui.kosmos.testScope import com.android.systemui.power.data.repository.fakePowerRepository import com.android.systemui.power.domain.interactor.powerInteractor @@ -43,6 +48,7 @@ import com.android.systemui.shade.domain.interactor.shadeInteractor import com.android.systemui.testKosmos import com.google.common.truth.Truth.assertThat import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.flowOf import kotlinx.coroutines.test.runCurrent import kotlinx.coroutines.test.runTest @@ -178,7 +184,11 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() { ) assertThat(executeDismissAction).isNull() + kosmos.fakeDeviceEntryFingerprintAuthRepository.setAuthenticationStatus( + SuccessFingerprintAuthenticationStatus(0, true) + ) kosmos.setSceneTransition(Idle(Scenes.Gone)) + kosmos.sceneInteractor.changeScene(Scenes.Gone, "") assertThat(executeDismissAction).isNotNull() } @@ -301,4 +311,78 @@ class KeyguardDismissActionInteractorTest : SysuiTestCase() { underTest.setKeyguardDone(KeyguardDone.IMMEDIATE) assertThat(keyguardDoneTiming).isEqualTo(KeyguardDone.IMMEDIATE) } + + @Test + @EnableSceneContainer + fun dismissAction_executesBeforeItsReset_sceneContainerOn_swipeAuth_fromQsScene() = + testScope.runTest { + val canSwipeToEnter by collectLastValue(kosmos.deviceEntryInteractor.canSwipeToEnter) + val currentScene by collectLastValue(kosmos.sceneInteractor.currentScene) + val transitionState = + MutableStateFlow<ObservableTransitionState>( + ObservableTransitionState.Idle(currentScene!!) + ) + kosmos.sceneInteractor.setTransitionState(transitionState) + val executeDismissAction by collectLastValue(underTest.executeDismissAction) + val resetDismissAction by collectLastValue(underTest.resetDismissAction) + assertThat(executeDismissAction).isNull() + assertThat(resetDismissAction).isNull() + kosmos.fakeAuthenticationRepository.setAuthenticationMethod( + AuthenticationMethodModel.None + ) + kosmos.fakeDeviceEntryRepository.setLockscreenEnabled(true) + assertThat(canSwipeToEnter).isTrue() + kosmos.sceneInteractor.changeScene(Scenes.QuickSettings, "") + transitionState.value = ObservableTransitionState.Idle(Scenes.QuickSettings) + assertThat(currentScene).isEqualTo(Scenes.QuickSettings) + + assertThat(executeDismissAction).isNull() + assertThat(resetDismissAction).isNull() + + val dismissAction = + DismissAction.RunImmediately( + onDismissAction = { KeyguardDone.LATER }, + onCancelAction = {}, + message = "message", + willAnimateOnLockscreen = true, + ) + underTest.setDismissAction(dismissAction) + // Should still be null because the transition to Gone has not yet happened. + assertThat(executeDismissAction).isNull() + assertThat(resetDismissAction).isNull() + + transitionState.value = + ObservableTransitionState.Transition.ChangeScene( + fromScene = Scenes.QuickSettings, + toScene = Scenes.Gone, + currentScene = flowOf(Scenes.QuickSettings), + currentOverlays = emptySet(), + progress = flowOf(0.5f), + isInitiatedByUserInput = true, + isUserInputOngoing = flowOf(false), + previewProgress = flowOf(0f), + isInPreviewStage = flowOf(false), + ) + runCurrent() + assertThat(executeDismissAction).isNull() + assertThat(resetDismissAction).isNull() + + transitionState.value = + ObservableTransitionState.Transition.ChangeScene( + fromScene = Scenes.QuickSettings, + toScene = Scenes.Gone, + currentScene = flowOf(Scenes.Gone), + currentOverlays = emptySet(), + progress = flowOf(1f), + isInitiatedByUserInput = true, + isUserInputOngoing = flowOf(false), + previewProgress = flowOf(0f), + isInPreviewStage = flowOf(false), + ) + kosmos.sceneInteractor.changeScene(Scenes.Gone, "") + assertThat(currentScene).isEqualTo(Scenes.Gone) + runCurrent() + assertThat(executeDismissAction).isNotNull() + assertThat(resetDismissAction).isNull() + } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt index 18b14951ee70..43f3649b0854 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardDismissActionInteractor.kt @@ -125,7 +125,20 @@ constructor( val executeDismissAction: Flow<() -> KeyguardDone> = merge( - finishedTransitionToGone, + if (SceneContainerFlag.isEnabled) { + // Using currentScene instead of finishedTransitionToGone because of a race + // condition that forms between finishedTransitionToGone and + // isOnShadeWhileUnlocked where the latter emits false before the former emits + // true, causing the merge to not emit until it's too late. + sceneInteractor + .get() + .currentScene + .map { it == Scenes.Gone } + .distinctUntilChanged() + .filter { it } + } else { + finishedTransitionToGone + }, isOnShadeWhileUnlocked.filter { it }.map {}, dismissInteractor.dismissKeyguardRequestWithImmediateDismissAction, ) @@ -135,10 +148,24 @@ constructor( val resetDismissAction: Flow<Unit> = combine( - transitionInteractor.isFinishedIn( - scene = Scenes.Gone, - stateWithoutSceneContainer = GONE, - ), + if (SceneContainerFlag.isEnabled) { + // Using currentScene instead of isFinishedIn because of a race condition that + // forms between isFinishedIn(Gone) and isOnShadeWhileUnlocked where the latter + // emits false before the former emits true, causing the evaluation of the + // combine to come up with true, temporarily, before settling on false, which is + // a valid final state. That causes an incorrect reset of the dismiss action to + // occur before it gets executed. + sceneInteractor + .get() + .currentScene + .map { it == Scenes.Gone } + .distinctUntilChanged() + } else { + transitionInteractor.isFinishedIn( + scene = Scenes.Gone, + stateWithoutSceneContainer = GONE, + ) + }, transitionInteractor.isFinishedIn( scene = Scenes.Bouncer, stateWithoutSceneContainer = PRIMARY_BOUNCER, |