diff options
| author | 2023-10-20 11:03:46 +0000 | |
|---|---|---|
| committer | 2023-10-20 11:03:46 +0000 | |
| commit | 69b2fb8335f7dfa1726a16e64bee70827d4fc6ff (patch) | |
| tree | 376687f8a2943d95794044dc9397e767e24120f8 | |
| parent | f2b3ab909d6b45848e51f96d431588c3bd5dc9f1 (diff) | |
| parent | e53baccc7fe006eac3b9da01785f0fd280bcec3f (diff) | |
Merge "Use keyguard transitions to ensure correct scrim" into main
9 files changed, 386 insertions, 101 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt index d06f31fed8db..7e360cfad66d 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/FromAlternateBouncerTransitionInteractor.kt @@ -26,13 +26,13 @@ import com.android.systemui.util.kotlin.Utils.Companion.toQuad import com.android.systemui.util.kotlin.Utils.Companion.toQuint import com.android.systemui.util.kotlin.sample import com.android.wm.shell.animation.Interpolators +import javax.inject.Inject +import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch -import javax.inject.Inject -import kotlin.time.Duration.Companion.milliseconds @SysUISingleton class FromAlternateBouncerTransitionInteractor @@ -130,11 +130,16 @@ constructor( override fun getDefaultAnimatorForTransitionsToState(toState: KeyguardState): ValueAnimator { return ValueAnimator().apply { interpolator = Interpolators.LINEAR - duration = TRANSITION_DURATION_MS.inWholeMilliseconds + duration = + when (toState) { + KeyguardState.GONE -> TO_GONE_DURATION + else -> TRANSITION_DURATION_MS + }.inWholeMilliseconds } } companion object { val TRANSITION_DURATION_MS = 300.milliseconds + val TO_GONE_DURATION = 500.milliseconds } } diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt index fbe26de4e9ba..b0b857729c77 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardTransitionInteractor.kt @@ -143,6 +143,11 @@ constructor( val dozingToLockscreenTransition: Flow<TransitionStep> = repository.transition(DOZING, LOCKSCREEN) + /** Receive all [TransitionStep] matching a filter of [from]->[to] */ + fun transition(from: KeyguardState, to: KeyguardState): Flow<TransitionStep> { + return repository.transition(from, to) + } + /** * AOD<->LOCKSCREEN transition information, mapped to dozeAmount range of AOD (1f) <-> * Lockscreen (0f). diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModel.kt new file mode 100644 index 000000000000..023d16cab013 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/AlternateBouncerToGoneTransitionViewModel.kt @@ -0,0 +1,42 @@ +/* + * 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.FromAlternateBouncerTransitionInteractor.Companion.TO_GONE_DURATION +import com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER +import com.android.systemui.keyguard.shared.model.ScrimAlpha +import javax.inject.Inject +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow + +/** + * Breaks down ALTERNATE_BOUNCER->GONE transition into discrete steps for corresponding views to + * consume. + */ +@OptIn(ExperimentalCoroutinesApi::class) +@SysUISingleton +class AlternateBouncerToGoneTransitionViewModel +@Inject +constructor( + bouncerToGoneFlows: BouncerToGoneFlows, +) { + + /** Scrim alpha values */ + val scrimAlpha: Flow<ScrimAlpha> = + bouncerToGoneFlows.scrimAlpha(TO_GONE_DURATION, ALTERNATE_BOUNCER) +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt new file mode 100644 index 000000000000..da74f2fa061e --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlows.kt @@ -0,0 +1,114 @@ +/* + * 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_ACCELERATE +import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor +import com.android.systemui.flags.FeatureFlagsClassic +import com.android.systemui.flags.Flags +import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.KeyguardState.GONE +import com.android.systemui.keyguard.shared.model.ScrimAlpha +import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow +import com.android.systemui.shade.domain.interactor.ShadeInteractor +import com.android.systemui.statusbar.SysuiStatusBarStateController +import dagger.Lazy +import javax.inject.Inject +import kotlin.time.Duration +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flatMapLatest +import kotlinx.coroutines.flow.map + +/** ALTERNATE and PRIMARY bouncers common animations */ +@OptIn(ExperimentalCoroutinesApi::class) +class BouncerToGoneFlows +@Inject +constructor( + private val interactor: KeyguardTransitionInteractor, + private val statusBarStateController: SysuiStatusBarStateController, + private val primaryBouncerInteractor: PrimaryBouncerInteractor, + private val keyguardDismissActionInteractor: Lazy<KeyguardDismissActionInteractor>, + private val featureFlags: FeatureFlagsClassic, + private val shadeInteractor: ShadeInteractor, +) { + /** Common fade for scrim alpha values during *BOUNCER->GONE */ + fun scrimAlpha(duration: Duration, fromState: KeyguardState): Flow<ScrimAlpha> { + return if (featureFlags.isEnabled(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT)) { + keyguardDismissActionInteractor + .get() + .willAnimateDismissActionOnLockscreen + .flatMapLatest { createScrimAlphaFlow(duration, fromState) { it } } + } else { + createScrimAlphaFlow( + duration, + fromState, + primaryBouncerInteractor::willRunDismissFromKeyguard + ) + } + } + + private fun createScrimAlphaFlow( + duration: Duration, + fromState: KeyguardState, + willRunAnimationOnKeyguard: () -> Boolean + ): Flow<ScrimAlpha> { + var isShadeExpanded = false + var leaveShadeOpen: Boolean = false + var willRunDismissFromKeyguard: Boolean = false + val transitionAnimation = + KeyguardTransitionAnimationFlow( + transitionDuration = duration, + transitionFlow = interactor.transition(fromState, GONE) + ) + + return shadeInteractor.shadeExpansion.flatMapLatest { shadeExpansion -> + transitionAnimation + .createFlow( + duration = duration, + interpolator = EMPHASIZED_ACCELERATE, + onStart = { + leaveShadeOpen = statusBarStateController.leaveOpenOnKeyguardHide() + willRunDismissFromKeyguard = willRunAnimationOnKeyguard() + isShadeExpanded = shadeExpansion > 0f + }, + onStep = { 1f - it }, + ) + .map { + if (willRunDismissFromKeyguard) { + if (isShadeExpanded) { + ScrimAlpha( + behindAlpha = it, + notificationsAlpha = it, + ) + } else { + ScrimAlpha() + } + } else if (leaveShadeOpen) { + ScrimAlpha( + behindAlpha = 1f, + notificationsAlpha = 1f, + ) + } else { + ScrimAlpha(behindAlpha = it) + } + } + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt index 078318196883..0e95be20d059 100644 --- a/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModel.kt @@ -16,7 +16,6 @@ package com.android.systemui.keyguard.ui.viewmodel -import com.android.app.animation.Interpolators.EMPHASIZED_ACCELERATE import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor import com.android.systemui.dagger.SysUISingleton import com.android.systemui.flags.FeatureFlagsClassic @@ -24,6 +23,8 @@ import com.android.systemui.flags.Flags import com.android.systemui.keyguard.domain.interactor.FromPrimaryBouncerTransitionInteractor.Companion.TO_GONE_DURATION import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor +import com.android.systemui.keyguard.shared.model.KeyguardState.GONE +import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER import com.android.systemui.keyguard.shared.model.ScrimAlpha import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow import com.android.systemui.statusbar.SysuiStatusBarStateController @@ -33,7 +34,6 @@ import kotlin.time.Duration.Companion.milliseconds import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flatMapLatest -import kotlinx.coroutines.flow.map /** * Breaks down PRIMARY_BOUNCER->GONE transition into discrete steps for corresponding views to @@ -49,11 +49,12 @@ constructor( private val primaryBouncerInteractor: PrimaryBouncerInteractor, keyguardDismissActionInteractor: Lazy<KeyguardDismissActionInteractor>, featureFlags: FeatureFlagsClassic, + bouncerToGoneFlows: BouncerToGoneFlows, ) { private val transitionAnimation = KeyguardTransitionAnimationFlow( transitionDuration = TO_GONE_DURATION, - transitionFlow = interactor.primaryBouncerToGoneTransition, + transitionFlow = interactor.transition(PRIMARY_BOUNCER, GONE) ) private var leaveShadeOpen: Boolean = false @@ -110,38 +111,6 @@ constructor( ) } - /** Scrim alpha values */ val scrimAlpha: Flow<ScrimAlpha> = - if (featureFlags.isEnabled(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT)) { - keyguardDismissActionInteractor - .get() - .willAnimateDismissActionOnLockscreen - .flatMapLatest { createScrimAlphaFlow { it } } - } else { - createScrimAlphaFlow(primaryBouncerInteractor::willRunDismissFromKeyguard) - } - private fun createScrimAlphaFlow(willRunAnimationOnKeyguard: () -> Boolean): Flow<ScrimAlpha> { - return transitionAnimation - .createFlow( - duration = TO_GONE_DURATION, - interpolator = EMPHASIZED_ACCELERATE, - onStart = { - leaveShadeOpen = statusBarStateController.leaveOpenOnKeyguardHide() - willRunDismissFromKeyguard = willRunAnimationOnKeyguard() - }, - onStep = { 1f - it }, - ) - .map { - if (willRunDismissFromKeyguard) { - ScrimAlpha() - } else if (leaveShadeOpen) { - ScrimAlpha( - behindAlpha = 1f, - notificationsAlpha = 1f, - ) - } else { - ScrimAlpha(behindAlpha = it) - } - } - } + bouncerToGoneFlows.scrimAlpha(TO_GONE_DURATION, PRIMARY_BOUNCER) } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java index 5b552640f397..744d70e36972 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java @@ -16,6 +16,9 @@ package com.android.systemui.statusbar.phone; +import static com.android.systemui.keyguard.shared.model.KeyguardState.ALTERNATE_BOUNCER; +import static com.android.systemui.keyguard.shared.model.KeyguardState.GONE; +import static com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER; import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow; import static java.lang.Float.isNaN; @@ -51,7 +54,6 @@ import com.android.settingslib.Utils; import com.android.systemui.CoreStartable; import com.android.systemui.DejankUtils; import com.android.systemui.Dumpable; -import com.android.systemui.res.R; import com.android.systemui.animation.ShadeInterpolation; import com.android.systemui.bouncer.shared.constants.KeyguardBouncerConstants; import com.android.systemui.dagger.SysUISingleton; @@ -62,7 +64,9 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInterac import com.android.systemui.keyguard.shared.model.ScrimAlpha; import com.android.systemui.keyguard.shared.model.TransitionState; import com.android.systemui.keyguard.shared.model.TransitionStep; +import com.android.systemui.keyguard.ui.viewmodel.AlternateBouncerToGoneTransitionViewModel; import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel; +import com.android.systemui.res.R; import com.android.systemui.scrim.ScrimView; import com.android.systemui.shade.ShadeViewController; import com.android.systemui.shade.transition.LargeScreenShadeInterpolator; @@ -273,6 +277,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump private CoroutineDispatcher mMainDispatcher; private boolean mIsBouncerToGoneTransitionRunning = false; private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel; + private AlternateBouncerToGoneTransitionViewModel mAlternateBouncerToGoneTransitionViewModel; private final Consumer<ScrimAlpha> mScrimAlphaConsumer = (ScrimAlpha alphas) -> { mInFrontAlpha = alphas.getFrontAlpha(); @@ -285,7 +290,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump mScrimBehind.setViewAlpha(mBehindAlpha); }; - Consumer<TransitionStep> mPrimaryBouncerToGoneTransition; + Consumer<TransitionStep> mBouncerToGoneTransition; @Inject public ScrimController( @@ -304,6 +309,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump KeyguardUnlockAnimationController keyguardUnlockAnimationController, StatusBarKeyguardViewManager statusBarKeyguardViewManager, PrimaryBouncerToGoneTransitionViewModel primaryBouncerToGoneTransitionViewModel, + AlternateBouncerToGoneTransitionViewModel alternateBouncerToGoneTransitionViewModel, KeyguardTransitionInteractor keyguardTransitionInteractor, WallpaperRepository wallpaperRepository, @Main CoroutineDispatcher mainDispatcher, @@ -349,6 +355,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump }); mColors = new GradientColors(); mPrimaryBouncerToGoneTransitionViewModel = primaryBouncerToGoneTransitionViewModel; + mAlternateBouncerToGoneTransitionViewModel = alternateBouncerToGoneTransitionViewModel; mKeyguardTransitionInteractor = keyguardTransitionInteractor; mWallpaperRepository = wallpaperRepository; mMainDispatcher = mainDispatcher; @@ -405,7 +412,7 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump // Directly control transition to UNLOCKED scrim state from PRIMARY_BOUNCER, and make sure // to report back that keyguard has faded away. This fixes cases where the scrim state was // rapidly switching on unlock, due to shifts in state in CentralSurfacesImpl - mPrimaryBouncerToGoneTransition = + mBouncerToGoneTransition = (TransitionStep step) -> { TransitionState state = step.getTransitionState(); @@ -425,10 +432,17 @@ public class ScrimController implements ViewTreeObserver.OnPreDrawListener, Dump } }; - collectFlow(behindScrim, mKeyguardTransitionInteractor.getPrimaryBouncerToGoneTransition(), - mPrimaryBouncerToGoneTransition, mMainDispatcher); + // PRIMARY_BOUNCER->GONE + collectFlow(behindScrim, mKeyguardTransitionInteractor.transition(PRIMARY_BOUNCER, GONE), + mBouncerToGoneTransition, mMainDispatcher); collectFlow(behindScrim, mPrimaryBouncerToGoneTransitionViewModel.getScrimAlpha(), mScrimAlphaConsumer, mMainDispatcher); + + // ALTERNATE_BOUNCER->GONE + collectFlow(behindScrim, mKeyguardTransitionInteractor.transition(ALTERNATE_BOUNCER, GONE), + mBouncerToGoneTransition, mMainDispatcher); + collectFlow(behindScrim, mAlternateBouncerToGoneTransitionViewModel.getScrimAlpha(), + mScrimAlphaConsumer, mMainDispatcher); } // TODO(b/270984686) recompute scrim height accurately, based on shade contents. diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsTest.kt new file mode 100644 index 000000000000..1ff46db99624 --- /dev/null +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/BouncerToGoneFlowsTest.kt @@ -0,0 +1,177 @@ +/* + * 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.bouncer.domain.interactor.PrimaryBouncerInteractor +import com.android.systemui.coroutines.collectValues +import com.android.systemui.flags.FakeFeatureFlags +import com.android.systemui.flags.Flags +import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepository +import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor +import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory +import com.android.systemui.keyguard.shared.model.KeyguardState +import com.android.systemui.keyguard.shared.model.KeyguardState.PRIMARY_BOUNCER +import com.android.systemui.keyguard.shared.model.ScrimAlpha +import com.android.systemui.keyguard.shared.model.TransitionState +import com.android.systemui.keyguard.shared.model.TransitionStep +import com.android.systemui.shade.domain.interactor.ShadeInteractor +import com.android.systemui.statusbar.SysuiStatusBarStateController +import com.android.systemui.util.mockito.whenever +import com.google.common.collect.Range +import com.google.common.truth.Truth.assertThat +import dagger.Lazy +import kotlin.time.Duration.Companion.milliseconds +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.UnconfinedTestDispatcher +import kotlinx.coroutines.test.runTest +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.MockitoAnnotations + +@SmallTest +@RunWith(AndroidJUnit4::class) +class BouncerToGoneFlowsTest : SysuiTestCase() { + private lateinit var underTest: BouncerToGoneFlows + private lateinit var repository: FakeKeyguardTransitionRepository + private lateinit var featureFlags: FakeFeatureFlags + @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController + @Mock private lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor + @Mock + private lateinit var keyguardDismissActionInteractor: Lazy<KeyguardDismissActionInteractor> + @Mock private lateinit var shadeInteractor: ShadeInteractor + + private val shadeExpansionStateFlow = MutableStateFlow(0.1f) + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + whenever(shadeInteractor.shadeExpansion).thenReturn(shadeExpansionStateFlow) + + repository = FakeKeyguardTransitionRepository() + val featureFlags = + FakeFeatureFlags().apply { set(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT, false) } + val interactor = + KeyguardTransitionInteractorFactory.create( + scope = TestScope().backgroundScope, + repository = repository, + ) + .keyguardTransitionInteractor + underTest = + BouncerToGoneFlows( + interactor, + statusBarStateController, + primaryBouncerInteractor, + keyguardDismissActionInteractor, + featureFlags, + shadeInteractor, + ) + + whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(false) + whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false) + } + + @Test + fun scrimAlpha_runDimissFromKeyguard_shadeExpanded() = + runTest(UnconfinedTestDispatcher()) { + val values by collectValues(underTest.scrimAlpha(500.milliseconds, PRIMARY_BOUNCER)) + shadeExpansionStateFlow.value = 1f + whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(true) + + repository.sendTransitionStep(step(0f, TransitionState.STARTED)) + repository.sendTransitionStep(step(0.3f)) + repository.sendTransitionStep(step(0.6f)) + repository.sendTransitionStep(step(1f)) + + assertThat(values.size).isEqualTo(4) + values.forEach { assertThat(it.frontAlpha).isEqualTo(0f) } + values.forEach { assertThat(it.behindAlpha).isIn(Range.closed(0f, 1f)) } + values.forEach { assertThat(it.notificationsAlpha).isIn(Range.closed(0f, 1f)) } + } + + @Test + fun scrimAlpha_runDimissFromKeyguard_shadeNotExpanded() = + runTest(UnconfinedTestDispatcher()) { + val values by collectValues(underTest.scrimAlpha(500.milliseconds, PRIMARY_BOUNCER)) + shadeExpansionStateFlow.value = 0f + + whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(true) + + repository.sendTransitionStep(step(0f, TransitionState.STARTED)) + repository.sendTransitionStep(step(0.3f)) + repository.sendTransitionStep(step(0.6f)) + repository.sendTransitionStep(step(1f)) + + assertThat(values.size).isEqualTo(4) + values.forEach { assertThat(it).isEqualTo(ScrimAlpha()) } + } + + @Test + fun scrimBehindAlpha_leaveShadeOpen() = + runTest(UnconfinedTestDispatcher()) { + val values by collectValues(underTest.scrimAlpha(500.milliseconds, PRIMARY_BOUNCER)) + + whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(true) + + repository.sendTransitionStep(step(0f, TransitionState.STARTED)) + repository.sendTransitionStep(step(0.3f)) + repository.sendTransitionStep(step(0.6f)) + repository.sendTransitionStep(step(1f)) + + assertThat(values.size).isEqualTo(4) + values.forEach { + assertThat(it).isEqualTo(ScrimAlpha(notificationsAlpha = 1f, behindAlpha = 1f)) + } + } + + @Test + fun scrimBehindAlpha_doNotLeaveShadeOpen() = + runTest(UnconfinedTestDispatcher()) { + val values by collectValues(underTest.scrimAlpha(500.milliseconds, PRIMARY_BOUNCER)) + + whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false) + + repository.sendTransitionStep(step(0f, TransitionState.STARTED)) + repository.sendTransitionStep(step(0.3f)) + repository.sendTransitionStep(step(0.6f)) + repository.sendTransitionStep(step(1f)) + + assertThat(values.size).isEqualTo(4) + values.forEach { assertThat(it.notificationsAlpha).isEqualTo(0f) } + values.forEach { assertThat(it.frontAlpha).isEqualTo(0f) } + values.forEach { assertThat(it.behindAlpha).isIn(Range.closed(0f, 1f)) } + assertThat(values[3].behindAlpha).isEqualTo(0f) + } + + private fun step( + value: Float, + state: TransitionState = TransitionState.RUNNING + ): TransitionStep { + return TransitionStep( + from = KeyguardState.PRIMARY_BOUNCER, + to = KeyguardState.GONE, + value = value, + transitionState = state, + ownerName = "PrimaryBouncerToGoneTransitionViewModelTest" + ) + } +} diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt index d7802aabb298..6cab023d59b0 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/ui/viewmodel/PrimaryBouncerToGoneTransitionViewModelTest.kt @@ -27,7 +27,6 @@ import com.android.systemui.keyguard.data.repository.FakeKeyguardTransitionRepos import com.android.systemui.keyguard.domain.interactor.KeyguardDismissActionInteractor import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractorFactory import com.android.systemui.keyguard.shared.model.KeyguardState -import com.android.systemui.keyguard.shared.model.ScrimAlpha import com.android.systemui.keyguard.shared.model.TransitionState import com.android.systemui.keyguard.shared.model.TransitionStep import com.android.systemui.statusbar.SysuiStatusBarStateController @@ -35,6 +34,7 @@ import com.android.systemui.util.mockito.whenever import com.google.common.collect.Range import com.google.common.truth.Truth.assertThat import dagger.Lazy +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.UnconfinedTestDispatcher import kotlinx.coroutines.test.runTest @@ -52,12 +52,16 @@ class PrimaryBouncerToGoneTransitionViewModelTest : SysuiTestCase() { private lateinit var featureFlags: FakeFeatureFlags @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController @Mock private lateinit var primaryBouncerInteractor: PrimaryBouncerInteractor + @Mock private lateinit var bouncerToGoneFlows: BouncerToGoneFlows @Mock private lateinit var keyguardDismissActionInteractor: Lazy<KeyguardDismissActionInteractor> + private val shadeExpansionStateFlow = MutableStateFlow(0.1f) + @Before fun setUp() { MockitoAnnotations.initMocks(this) + repository = FakeKeyguardTransitionRepository() val featureFlags = FakeFeatureFlags().apply { set(Flags.REFACTOR_KEYGUARD_DISMISS_INTENT, false) } @@ -74,6 +78,7 @@ class PrimaryBouncerToGoneTransitionViewModelTest : SysuiTestCase() { primaryBouncerInteractor, keyguardDismissActionInteractor, featureFlags, + bouncerToGoneFlows, ) whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(false) @@ -148,59 +153,6 @@ class PrimaryBouncerToGoneTransitionViewModelTest : SysuiTestCase() { values.forEach { assertThat(it).isEqualTo(1f) } } - @Test - fun scrimAlpha_runDimissFromKeyguard() = - runTest(UnconfinedTestDispatcher()) { - val values by collectValues(underTest.scrimAlpha) - - whenever(primaryBouncerInteractor.willRunDismissFromKeyguard()).thenReturn(true) - - repository.sendTransitionStep(step(0f, TransitionState.STARTED)) - repository.sendTransitionStep(step(0.3f)) - repository.sendTransitionStep(step(0.6f)) - repository.sendTransitionStep(step(1f)) - - assertThat(values.size).isEqualTo(4) - values.forEach { assertThat(it).isEqualTo(ScrimAlpha()) } - } - - @Test - fun scrimBehindAlpha_leaveShadeOpen() = - runTest(UnconfinedTestDispatcher()) { - val values by collectValues(underTest.scrimAlpha) - - whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(true) - - repository.sendTransitionStep(step(0f, TransitionState.STARTED)) - repository.sendTransitionStep(step(0.3f)) - repository.sendTransitionStep(step(0.6f)) - repository.sendTransitionStep(step(1f)) - - assertThat(values.size).isEqualTo(4) - values.forEach { - assertThat(it).isEqualTo(ScrimAlpha(notificationsAlpha = 1f, behindAlpha = 1f)) - } - } - - @Test - fun scrimBehindAlpha_doNotLeaveShadeOpen() = - runTest(UnconfinedTestDispatcher()) { - val values by collectValues(underTest.scrimAlpha) - - whenever(statusBarStateController.leaveOpenOnKeyguardHide()).thenReturn(false) - - repository.sendTransitionStep(step(0f, TransitionState.STARTED)) - repository.sendTransitionStep(step(0.3f)) - repository.sendTransitionStep(step(0.6f)) - repository.sendTransitionStep(step(1f)) - - assertThat(values.size).isEqualTo(4) - values.forEach { assertThat(it.notificationsAlpha).isEqualTo(0f) } - values.forEach { assertThat(it.frontAlpha).isEqualTo(0f) } - values.forEach { assertThat(it.behindAlpha).isIn(Range.closed(0f, 1f)) } - assertThat(values[3].behindAlpha).isEqualTo(0f) - } - private fun step( value: Float, state: TransitionState = TransitionState.RUNNING diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java index 6b3bd22d5e62..15c09b53938f 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ScrimControllerTest.java @@ -70,6 +70,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInterac 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.keyguard.ui.viewmodel.AlternateBouncerToGoneTransitionViewModel; import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel; import com.android.systemui.scrim.ScrimView; import com.android.systemui.shade.transition.LargeScreenShadeInterpolator; @@ -141,6 +142,8 @@ public class ScrimControllerTest extends SysuiTestCase { @Mock private ScreenOffAnimationController mScreenOffAnimationController; @Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController; @Mock private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel; + @Mock private AlternateBouncerToGoneTransitionViewModel + mAlternateBouncerToGoneTransitionViewModel; @Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor; private final FakeWallpaperRepository mWallpaperRepository = new FakeWallpaperRepository(); @Mock private CoroutineDispatcher mMainDispatcher; @@ -264,10 +267,12 @@ public class ScrimControllerTest extends SysuiTestCase { when(mDelayedWakeLockBuilder.build()).thenReturn(mWakeLock); when(mDockManager.isDocked()).thenReturn(false); - when(mKeyguardTransitionInteractor.getPrimaryBouncerToGoneTransition()) + when(mKeyguardTransitionInteractor.transition(any(), any())) .thenReturn(emptyFlow()); when(mPrimaryBouncerToGoneTransitionViewModel.getScrimAlpha()) .thenReturn(emptyFlow()); + when(mAlternateBouncerToGoneTransitionViewModel.getScrimAlpha()) + .thenReturn(emptyFlow()); mScrimController = new ScrimController( mLightBarController, @@ -285,6 +290,7 @@ public class ScrimControllerTest extends SysuiTestCase { mKeyguardUnlockAnimationController, mStatusBarKeyguardViewManager, mPrimaryBouncerToGoneTransitionViewModel, + mAlternateBouncerToGoneTransitionViewModel, mKeyguardTransitionInteractor, mWallpaperRepository, mMainDispatcher, @@ -992,6 +998,7 @@ public class ScrimControllerTest extends SysuiTestCase { mKeyguardUnlockAnimationController, mStatusBarKeyguardViewManager, mPrimaryBouncerToGoneTransitionViewModel, + mAlternateBouncerToGoneTransitionViewModel, mKeyguardTransitionInteractor, mWallpaperRepository, mMainDispatcher, @@ -1775,7 +1782,7 @@ public class ScrimControllerTest extends SysuiTestCase { @Test public void ignoreTransitionRequestWhileKeyguardTransitionRunning() { mScrimController.transitionTo(ScrimState.UNLOCKED); - mScrimController.mPrimaryBouncerToGoneTransition.accept( + mScrimController.mBouncerToGoneTransition.accept( new TransitionStep(KeyguardState.PRIMARY_BOUNCER, KeyguardState.GONE, 0f, TransitionState.RUNNING, "ScrimControllerTest")); @@ -1787,7 +1794,7 @@ public class ScrimControllerTest extends SysuiTestCase { @Test public void primaryBouncerToGoneOnFinishCallsKeyguardFadedAway() { when(mKeyguardStateController.isKeyguardFadingAway()).thenReturn(true); - mScrimController.mPrimaryBouncerToGoneTransition.accept( + mScrimController.mBouncerToGoneTransition.accept( new TransitionStep(KeyguardState.PRIMARY_BOUNCER, KeyguardState.GONE, 0f, TransitionState.FINISHED, "ScrimControllerTest")); |