Loading packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt +1 −10 Original line number Diff line number Diff line Loading @@ -127,16 +127,7 @@ private class PredictiveBackTransition( return coroutineScope .launch(start = CoroutineStart.ATOMIC) { try { if (currentScene == toScene) { animatable.animateTo(targetProgress, transformationSpec.progressSpec) } else { // If the back gesture is cancelled, the progress is animated back to 0f by // the system. But we need this animate call anyways because // PredictiveBackHandler doesn't guarantee that it ends at 0f. Since the // remaining change in progress is usually very small, the progressSpec is // omitted and the default spring spec used instead. animatable.animateTo(targetProgress) } } finally { state.finishTransition(this@PredictiveBackTransition, scene) } Loading packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt +1 −34 Original line number Diff line number Diff line Loading @@ -18,8 +18,6 @@ package com.android.compose.animation.scene import androidx.activity.BackEventCompat import androidx.activity.ComponentActivity import androidx.compose.animation.core.LinearEasing import androidx.compose.animation.core.tween import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.rememberCoroutineScope Loading Loading @@ -61,23 +59,7 @@ class PredictiveBackHandlerTest { @Test fun testPredictiveBack() { val transitionFrames = 2 val layoutState = rule.runOnUiThread { MutableSceneTransitionLayoutState( SceneA, transitions = transitions { from(SceneA, to = SceneB) { spec = tween( durationMillis = transitionFrames * 16, easing = LinearEasing ) } } ) } val layoutState = rule.runOnUiThread { MutableSceneTransitionLayoutState(SceneA) } rule.setContent { SceneTransitionLayout(layoutState) { scene(SceneA, mapOf(Back to SceneB)) { Box(Modifier.fillMaxSize()) } Loading Loading @@ -106,27 +88,12 @@ class PredictiveBackHandlerTest { assertThat(layoutState.transitionState).hasCurrentScene(SceneA) assertThat(layoutState.transitionState).isIdle() rule.mainClock.autoAdvance = false // Start again and commit it. rule.runOnUiThread { dispatcher.dispatchOnBackStarted(backEvent()) dispatcher.dispatchOnBackProgressed(backEvent(progress = 0.4f)) dispatcher.onBackPressed() } rule.mainClock.advanceTimeByFrame() rule.waitForIdle() val transition2 = assertThat(layoutState.transitionState).isTransition() // verify that transition picks up progress from preview assertThat(transition2).hasProgress(0.4f, tolerance = 0.0001f) rule.mainClock.advanceTimeByFrame() rule.waitForIdle() // verify that transition is half way between preview-end-state (0.4f) and target-state (1f) // after one frame assertThat(transition2).hasProgress(0.7f, tolerance = 0.0001f) rule.mainClock.autoAdvance = true rule.waitForIdle() assertThat(layoutState.transitionState).hasCurrentScene(SceneB) assertThat(layoutState.transitionState).isIdle() Loading Loading
packages/SystemUI/compose/scene/src/com/android/compose/animation/scene/PredictiveBackHandler.kt +1 −10 Original line number Diff line number Diff line Loading @@ -127,16 +127,7 @@ private class PredictiveBackTransition( return coroutineScope .launch(start = CoroutineStart.ATOMIC) { try { if (currentScene == toScene) { animatable.animateTo(targetProgress, transformationSpec.progressSpec) } else { // If the back gesture is cancelled, the progress is animated back to 0f by // the system. But we need this animate call anyways because // PredictiveBackHandler doesn't guarantee that it ends at 0f. Since the // remaining change in progress is usually very small, the progressSpec is // omitted and the default spring spec used instead. animatable.animateTo(targetProgress) } } finally { state.finishTransition(this@PredictiveBackTransition, scene) } Loading
packages/SystemUI/compose/scene/tests/src/com/android/compose/animation/scene/PredictiveBackHandlerTest.kt +1 −34 Original line number Diff line number Diff line Loading @@ -18,8 +18,6 @@ package com.android.compose.animation.scene import androidx.activity.BackEventCompat import androidx.activity.ComponentActivity import androidx.compose.animation.core.LinearEasing import androidx.compose.animation.core.tween import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.runtime.rememberCoroutineScope Loading Loading @@ -61,23 +59,7 @@ class PredictiveBackHandlerTest { @Test fun testPredictiveBack() { val transitionFrames = 2 val layoutState = rule.runOnUiThread { MutableSceneTransitionLayoutState( SceneA, transitions = transitions { from(SceneA, to = SceneB) { spec = tween( durationMillis = transitionFrames * 16, easing = LinearEasing ) } } ) } val layoutState = rule.runOnUiThread { MutableSceneTransitionLayoutState(SceneA) } rule.setContent { SceneTransitionLayout(layoutState) { scene(SceneA, mapOf(Back to SceneB)) { Box(Modifier.fillMaxSize()) } Loading Loading @@ -106,27 +88,12 @@ class PredictiveBackHandlerTest { assertThat(layoutState.transitionState).hasCurrentScene(SceneA) assertThat(layoutState.transitionState).isIdle() rule.mainClock.autoAdvance = false // Start again and commit it. rule.runOnUiThread { dispatcher.dispatchOnBackStarted(backEvent()) dispatcher.dispatchOnBackProgressed(backEvent(progress = 0.4f)) dispatcher.onBackPressed() } rule.mainClock.advanceTimeByFrame() rule.waitForIdle() val transition2 = assertThat(layoutState.transitionState).isTransition() // verify that transition picks up progress from preview assertThat(transition2).hasProgress(0.4f, tolerance = 0.0001f) rule.mainClock.advanceTimeByFrame() rule.waitForIdle() // verify that transition is half way between preview-end-state (0.4f) and target-state (1f) // after one frame assertThat(transition2).hasProgress(0.7f, tolerance = 0.0001f) rule.mainClock.autoAdvance = true rule.waitForIdle() assertThat(layoutState.transitionState).hasCurrentScene(SceneB) assertThat(layoutState.transitionState).isIdle() Loading