Loading packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModelTest.kt +25 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,31 @@ class GlanceableHubToLockscreenTransitionViewModelTest : SysuiTestCase() { values.forEach { assertThat(it.value).isIn(Range.closed(-100f, 0f)) } } @Test fun lockscreenTranslationX_resetsAfterCancellation() = testScope.runTest { configurationRepository.setDimensionPixelSize( R.dimen.hub_to_lockscreen_transition_lockscreen_translation_x, 100 ) val values by collectValues(underTest.keyguardTranslationX) assertThat(values).isEmpty() keyguardTransitionRepository.sendTransitionSteps( listOf( step(0f, TransitionState.STARTED), step(0.3f), step(0.5f), step(0.9f, TransitionState.CANCELED) ), testScope, ) assertThat(values).hasSize(4) values.forEach { assertThat(it.value).isIn(Range.closed(-100f, 0f)) } assertThat(values.last().value).isEqualTo(0f) } private fun step( value: Float, state: TransitionState = TransitionState.RUNNING Loading packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt +5 −0 Original line number Diff line number Diff line Loading @@ -159,6 +159,11 @@ class KeyguardTransitionRepositoryImpl @Inject constructor() : KeyguardTransitio lastAnimator?.cancel() lastAnimator = info.animator // Cancel any existing manual transitions updateTransitionId?.let { uuid -> updateTransition(uuid, lastStep.value, TransitionState.CANCELED) } info.animator?.let { animator -> // An animator was provided, so use it to run the transition animator.setFloatValues(startingValue, 1f) Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModel.kt +5 −1 Original line number Diff line number Diff line Loading @@ -72,7 +72,11 @@ constructor( duration = TO_LOCKSCREEN_DURATION, onStep = { value -> -translatePx + value * translatePx }, interpolator = EMPHASIZED, onCancel = { -translatePx.toFloat() }, // Move notifications back to their original position since they can be // accessed from the shade, and also keyguard elements in case the animation // is cancelled. onFinish = { 0f }, onCancel = { 0f }, name = "GLANCEABLE_HUB->LOCKSCREEN: keyguardTranslationX" ) } Loading packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModel.kt +2 −1 Original line number Diff line number Diff line Loading @@ -71,7 +71,8 @@ constructor( duration = FromLockscreenTransitionInteractor.TO_GLANCEABLE_HUB_DURATION, onStep = { value -> value * translatePx }, // Move notifications back to their original position since they can be // accessed from the shade. // accessed from the shade, and also keyguard elements in case the animation // is cancelled. onFinish = { 0f }, onCancel = { 0f }, interpolator = EMPHASIZED, Loading packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt +99 −0 Original line number Diff line number Diff line Loading @@ -27,7 +27,9 @@ import com.android.app.animation.Interpolators import com.android.systemui.SysuiTestCase import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardState.AOD import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.KeyguardState.OFF import com.android.systemui.keyguard.shared.model.TransitionInfo import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled import com.android.systemui.keyguard.shared.model.TransitionState Loading @@ -37,6 +39,7 @@ import com.google.common.truth.Truth.assertThat import java.math.BigDecimal import java.math.RoundingMode import java.util.UUID import kotlinx.coroutines.flow.dropWhile import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.test.TestScope Loading Loading @@ -223,6 +226,101 @@ class KeyguardTransitionRepositoryTest : SysuiTestCase() { job.cancel() } @Test fun startingSecondManualTransitionWillCancelPreviousManualTransition() = TestScope().runTest { // Drop initial steps from OFF which are sent in the constructor val steps = mutableListOf<TransitionStep>() val job = underTest.transitions .dropWhile { step -> step.from == OFF } .onEach { steps.add(it) } .launchIn(this) val firstUuid = underTest.startTransition( TransitionInfo(OWNER_NAME, AOD, LOCKSCREEN, animator = null) ) runCurrent() checkNotNull(firstUuid) underTest.updateTransition(firstUuid, 0.5f, TransitionState.RUNNING) runCurrent() val secondUuid = underTest.startTransition( TransitionInfo(OWNER_NAME, AOD, DREAMING, animator = null) ) runCurrent() checkNotNull(secondUuid) underTest.updateTransition(secondUuid, 0.7f, TransitionState.RUNNING) // Trying to transition the old uuid should be ignored. underTest.updateTransition(firstUuid, 0.6f, TransitionState.RUNNING) runCurrent() assertThat(steps) .containsExactly( TransitionStep(AOD, LOCKSCREEN, 0f, TransitionState.STARTED, OWNER_NAME), TransitionStep(AOD, LOCKSCREEN, 0.5f, TransitionState.RUNNING, OWNER_NAME), TransitionStep(AOD, LOCKSCREEN, 0.5f, TransitionState.CANCELED, OWNER_NAME), TransitionStep(AOD, DREAMING, 0.5f, TransitionState.STARTED, OWNER_NAME), TransitionStep(AOD, DREAMING, 0.7f, TransitionState.RUNNING, OWNER_NAME), ) .inOrder() job.cancel() } @Test fun startingSecondTransitionWillCancelPreviousManualTransition() = TestScope().runTest { // Drop initial steps from OFF which are sent in the constructor val steps = mutableListOf<TransitionStep>() val job = underTest.transitions .dropWhile { step -> step.from == OFF } .onEach { steps.add(it) } .launchIn(this) val uuid = underTest.startTransition( TransitionInfo(OWNER_NAME, AOD, LOCKSCREEN, animator = null) ) runCurrent() checkNotNull(uuid) underTest.updateTransition(uuid, 0.5f, TransitionState.RUNNING) runCurrent() // Start new transition to dreaming, should cancel previous one. runner.startTransition( this, TransitionInfo( OWNER_NAME, AOD, DREAMING, getAnimator(), TransitionModeOnCanceled.RESET, ), ) runCurrent() // Trying to transition the old uuid should be ignored. underTest.updateTransition(uuid, 0.6f, TransitionState.RUNNING) runCurrent() assertThat(steps.take(3)) .containsExactly( TransitionStep(AOD, LOCKSCREEN, 0f, TransitionState.STARTED, OWNER_NAME), TransitionStep(AOD, LOCKSCREEN, 0.5f, TransitionState.RUNNING, OWNER_NAME), TransitionStep(AOD, LOCKSCREEN, 0.5f, TransitionState.CANCELED, OWNER_NAME), ) .inOrder() job.cancel() } @Test fun attemptTomanuallyUpdateTransitionWithInvalidUUIDthrowsException() { underTest.updateTransition(UUID.randomUUID(), 0f, TransitionState.RUNNING) Loading Loading @@ -336,6 +434,7 @@ class KeyguardTransitionRepositoryTest : SysuiTestCase() { private class WtfHandler : TerribleFailureHandler { var failed = false override fun onTerribleFailure(tag: String, what: TerribleFailure, system: Boolean) { failed = true } Loading Loading
packages/SystemUI/multivalentTests/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModelTest.kt +25 −0 Original line number Diff line number Diff line Loading @@ -99,6 +99,31 @@ class GlanceableHubToLockscreenTransitionViewModelTest : SysuiTestCase() { values.forEach { assertThat(it.value).isIn(Range.closed(-100f, 0f)) } } @Test fun lockscreenTranslationX_resetsAfterCancellation() = testScope.runTest { configurationRepository.setDimensionPixelSize( R.dimen.hub_to_lockscreen_transition_lockscreen_translation_x, 100 ) val values by collectValues(underTest.keyguardTranslationX) assertThat(values).isEmpty() keyguardTransitionRepository.sendTransitionSteps( listOf( step(0f, TransitionState.STARTED), step(0.3f), step(0.5f), step(0.9f, TransitionState.CANCELED) ), testScope, ) assertThat(values).hasSize(4) values.forEach { assertThat(it.value).isIn(Range.closed(-100f, 0f)) } assertThat(values.last().value).isEqualTo(0f) } private fun step( value: Float, state: TransitionState = TransitionState.RUNNING Loading
packages/SystemUI/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepository.kt +5 −0 Original line number Diff line number Diff line Loading @@ -159,6 +159,11 @@ class KeyguardTransitionRepositoryImpl @Inject constructor() : KeyguardTransitio lastAnimator?.cancel() lastAnimator = info.animator // Cancel any existing manual transitions updateTransitionId?.let { uuid -> updateTransition(uuid, lastStep.value, TransitionState.CANCELED) } info.animator?.let { animator -> // An animator was provided, so use it to run the transition animator.setFloatValues(startingValue, 1f) Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/GlanceableHubToLockscreenTransitionViewModel.kt +5 −1 Original line number Diff line number Diff line Loading @@ -72,7 +72,11 @@ constructor( duration = TO_LOCKSCREEN_DURATION, onStep = { value -> -translatePx + value * translatePx }, interpolator = EMPHASIZED, onCancel = { -translatePx.toFloat() }, // Move notifications back to their original position since they can be // accessed from the shade, and also keyguard elements in case the animation // is cancelled. onFinish = { 0f }, onCancel = { 0f }, name = "GLANCEABLE_HUB->LOCKSCREEN: keyguardTranslationX" ) } Loading
packages/SystemUI/src/com/android/systemui/keyguard/ui/viewmodel/LockscreenToGlanceableHubTransitionViewModel.kt +2 −1 Original line number Diff line number Diff line Loading @@ -71,7 +71,8 @@ constructor( duration = FromLockscreenTransitionInteractor.TO_GLANCEABLE_HUB_DURATION, onStep = { value -> value * translatePx }, // Move notifications back to their original position since they can be // accessed from the shade. // accessed from the shade, and also keyguard elements in case the animation // is cancelled. onFinish = { 0f }, onCancel = { 0f }, interpolator = EMPHASIZED, Loading
packages/SystemUI/tests/src/com/android/systemui/keyguard/data/repository/KeyguardTransitionRepositoryTest.kt +99 −0 Original line number Diff line number Diff line Loading @@ -27,7 +27,9 @@ import com.android.app.animation.Interpolators import com.android.systemui.SysuiTestCase import com.android.systemui.keyguard.shared.model.KeyguardState import com.android.systemui.keyguard.shared.model.KeyguardState.AOD import com.android.systemui.keyguard.shared.model.KeyguardState.DREAMING import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN import com.android.systemui.keyguard.shared.model.KeyguardState.OFF import com.android.systemui.keyguard.shared.model.TransitionInfo import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled import com.android.systemui.keyguard.shared.model.TransitionState Loading @@ -37,6 +39,7 @@ import com.google.common.truth.Truth.assertThat import java.math.BigDecimal import java.math.RoundingMode import java.util.UUID import kotlinx.coroutines.flow.dropWhile import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.test.TestScope Loading Loading @@ -223,6 +226,101 @@ class KeyguardTransitionRepositoryTest : SysuiTestCase() { job.cancel() } @Test fun startingSecondManualTransitionWillCancelPreviousManualTransition() = TestScope().runTest { // Drop initial steps from OFF which are sent in the constructor val steps = mutableListOf<TransitionStep>() val job = underTest.transitions .dropWhile { step -> step.from == OFF } .onEach { steps.add(it) } .launchIn(this) val firstUuid = underTest.startTransition( TransitionInfo(OWNER_NAME, AOD, LOCKSCREEN, animator = null) ) runCurrent() checkNotNull(firstUuid) underTest.updateTransition(firstUuid, 0.5f, TransitionState.RUNNING) runCurrent() val secondUuid = underTest.startTransition( TransitionInfo(OWNER_NAME, AOD, DREAMING, animator = null) ) runCurrent() checkNotNull(secondUuid) underTest.updateTransition(secondUuid, 0.7f, TransitionState.RUNNING) // Trying to transition the old uuid should be ignored. underTest.updateTransition(firstUuid, 0.6f, TransitionState.RUNNING) runCurrent() assertThat(steps) .containsExactly( TransitionStep(AOD, LOCKSCREEN, 0f, TransitionState.STARTED, OWNER_NAME), TransitionStep(AOD, LOCKSCREEN, 0.5f, TransitionState.RUNNING, OWNER_NAME), TransitionStep(AOD, LOCKSCREEN, 0.5f, TransitionState.CANCELED, OWNER_NAME), TransitionStep(AOD, DREAMING, 0.5f, TransitionState.STARTED, OWNER_NAME), TransitionStep(AOD, DREAMING, 0.7f, TransitionState.RUNNING, OWNER_NAME), ) .inOrder() job.cancel() } @Test fun startingSecondTransitionWillCancelPreviousManualTransition() = TestScope().runTest { // Drop initial steps from OFF which are sent in the constructor val steps = mutableListOf<TransitionStep>() val job = underTest.transitions .dropWhile { step -> step.from == OFF } .onEach { steps.add(it) } .launchIn(this) val uuid = underTest.startTransition( TransitionInfo(OWNER_NAME, AOD, LOCKSCREEN, animator = null) ) runCurrent() checkNotNull(uuid) underTest.updateTransition(uuid, 0.5f, TransitionState.RUNNING) runCurrent() // Start new transition to dreaming, should cancel previous one. runner.startTransition( this, TransitionInfo( OWNER_NAME, AOD, DREAMING, getAnimator(), TransitionModeOnCanceled.RESET, ), ) runCurrent() // Trying to transition the old uuid should be ignored. underTest.updateTransition(uuid, 0.6f, TransitionState.RUNNING) runCurrent() assertThat(steps.take(3)) .containsExactly( TransitionStep(AOD, LOCKSCREEN, 0f, TransitionState.STARTED, OWNER_NAME), TransitionStep(AOD, LOCKSCREEN, 0.5f, TransitionState.RUNNING, OWNER_NAME), TransitionStep(AOD, LOCKSCREEN, 0.5f, TransitionState.CANCELED, OWNER_NAME), ) .inOrder() job.cancel() } @Test fun attemptTomanuallyUpdateTransitionWithInvalidUUIDthrowsException() { underTest.updateTransition(UUID.randomUUID(), 0f, TransitionState.RUNNING) Loading Loading @@ -336,6 +434,7 @@ class KeyguardTransitionRepositoryTest : SysuiTestCase() { private class WtfHandler : TerribleFailureHandler { var failed = false override fun onTerribleFailure(tag: String, what: TerribleFailure, system: Boolean) { failed = true } Loading