Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 00970c7e authored by Jordan Demeulenaere's avatar Jordan Demeulenaere Committed by Android (Google) Code Review
Browse files

Merge changes Ibe58a3dc,Ie3eccc40,Ifb2ee648,I12876009 into main

* changes:
  Enable deferTransitionProgress in Flexiglass
  Add overscroll effect to the QS scene
  Don't decay when it will be too slow
  Use slowSpatialSpec() when flinging and animating to targetOffset
parents 79a83b7e b6891b95
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.overscroll
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.windowsizeclass.WindowWidthSizeClass
@@ -311,6 +312,7 @@ private fun ContentScope.QuickSettingsScene(
            horizontalAlignment = Alignment.CenterHorizontally,
            modifier =
                Modifier.fillMaxSize()
                    .overscroll(verticalOverscrollEffect)
                    .padding(
                        top = topPadding.coerceAtLeast(0.dp),
                        bottom = bottomPadding.coerceAtLeast(0.dp),
+1 −0
Original line number Diff line number Diff line
@@ -141,6 +141,7 @@ fun SceneContainer(
                    cuj = transition.cuj,
                )
            },
            deferTransitionProgress = true,
        )

    DisposableEffect(state) {
+118 −3
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import androidx.compose.animation.core.Animatable
import androidx.compose.animation.core.AnimationSpec
import androidx.compose.animation.core.AnimationVector1D
import androidx.compose.animation.core.DecayAnimationSpec
import androidx.compose.animation.core.VectorConverter
import androidx.compose.animation.core.calculateTargetValue
import androidx.compose.foundation.gestures.Orientation
import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
@@ -413,7 +414,19 @@ internal class SwipeAnimation<T : ContentKey>(
                else -> error("Target $targetOffset should be $lowerBound or $upperBound")
            }

        if (willDecayReachBounds) {
        // TODO(b/417444347): Use the default or fast spatial spec for small STLs, or make it a
        // parameter of the transitions spec.
        val animationSpec = spec ?: layoutState.motionScheme.slowSpatialSpec()
        if (
            willDecayReachBounds &&
                willDecayFasterThanAnimating(
                    animationSpec,
                    decayAnimationSpec,
                    initialOffset,
                    targetOffset,
                    initialVelocity,
                )
        ) {
            val result = animatable.animateDecay(initialVelocity, decayAnimationSpec)
            check(animatable.value == targetOffset) {
                buildString {
@@ -433,10 +446,9 @@ internal class SwipeAnimation<T : ContentKey>(
            return initialVelocity - result.endState.velocity
        }

        val motionSpatialSpec = spec ?: layoutState.motionScheme.defaultSpatialSpec()
        animatable.animateTo(
            targetValue = targetOffset,
            animationSpec = motionSpatialSpec,
            animationSpec = animationSpec,
            initialVelocity = initialVelocity,
        )

@@ -475,6 +487,106 @@ internal class SwipeAnimation<T : ContentKey>(
    }
}

internal fun willDecayFasterThanAnimating(
    animationSpec: AnimationSpec<Float>,
    decayAnimationSpec: DecayAnimationSpec<Float>,
    initialOffset: Float,
    targetOffset: Float,
    initialVelocity: Float,
): Boolean {
    if (initialOffset == targetOffset) {
        return true
    }

    fun hasReachedTargetOffset(value: Float): Boolean {
        return when {
            initialOffset < targetOffset -> value >= targetOffset
            else -> value <= targetOffset
        }
    }

    val converter = Float.VectorConverter
    val decayAnimationSpecVector = decayAnimationSpec.vectorize(converter)
    val initialOffsetVector = converter.convertToVector(initialOffset)
    val initialVelocityVector = converter.convertToVector(initialVelocity)

    // Given that the Animatable that we are going to animate with animationSpec or
    // decayAnimationSpec has bounds and will stop as soon as the targetOffset is reached, we
    // can not use the getDurationNanos() API from VectorizedAnimationSpec and
    // VectorizedDecayAnimationSpec.
    //
    // For the decay, we can use a simple binary search given that once the decay has reached
    // the target value it will never change direction.
    val decayDuration = binarySearch { timeMs ->
        hasReachedTargetOffset(
            converter.convertFromVector(
                decayAnimationSpecVector.getValueFromNanos(
                    playTimeNanos = timeMs * MillisToNanos,
                    initialValue = initialOffsetVector,
                    initialVelocity = initialVelocityVector,
                )
            )
        )
    }

    // For the animation we can't use binary search given that springs and eased interpolations
    // can oscillate around the target offset. Given that it's ok to estimate this duration, we
    // simply check whether we passed the threshold for each single frame step time (~8ms).
    val animationSpecVector = animationSpec.vectorize(converter)
    val targetOffsetVector = converter.convertToVector(targetOffset)
    val maxAnimationDurationMs =
        animationSpecVector.getDurationNanos(
            initialOffsetVector,
            targetOffsetVector,
            initialVelocityVector,
        ) / MillisToNanos
    var animationDurationMs = 0
    var hasReachedTarget = false
    while (!hasReachedTarget && animationDurationMs < maxAnimationDurationMs) {
        animationDurationMs += ApproximateFrameTime
        hasReachedTarget =
            hasReachedTargetOffset(
                converter.convertFromVector(
                    animationSpecVector.getValueFromNanos(
                        playTimeNanos = animationDurationMs * MillisToNanos,
                        initialValue = initialOffsetVector,
                        initialVelocity = initialVelocityVector,
                        targetValue = targetOffsetVector,
                    )
                )
            )
    }

    return decayDuration <= animationDurationMs
}

/** Returns the lowest timeMs >= 0 for which [f] is true. */
private fun binarySearch(f: (timeMs: Long) -> Boolean): Long {
    check(!f(0)) { "f should return false for timeMillis=0" }
    var low = 0L
    var high = 128L // common duration that is also a power of 2.
    while (!f(high)) {
        if (high > Long.MAX_VALUE / 2) {
            error("overflow, f($high) returned false")
        }

        low = high
        high *= 2
    }

    var result = high
    while (low <= high) {
        val mid = low + (high - low) / 2
        if (f(mid)) {
            result = mid
            high = mid - 1
        } else {
            low = mid + 1
        }
    }
    return result
}

private object DefaultSwipeDistance : UserActionDistance {
    override fun UserActionDistanceScope.absoluteDistance(
        fromContent: ContentKey,
@@ -639,3 +751,6 @@ private class ReplaceOverlaySwipeTransition(
        swipeAnimation.freezeAndAnimateToCurrentState()
    }
}

private const val MillisToNanos = 1_000_000L
private const val ApproximateFrameTime = 1_000 / 120
+61 −71
Original line number Diff line number Diff line
@@ -58,8 +58,7 @@
    880,
    896,
    912,
    928,
    944
    928
  ],
  "features": [
    {
@@ -223,59 +222,55 @@
          "y": 5.2
        },
        {
          "x": 8.4,
          "x": 5.6,
          "y": 5.2
        },
        {
          "x": 11.2,
          "x": 7.6,
          "y": 5.2
        },
        {
          "x": 13.6,
          "x": 9.6,
          "y": 5.2
        },
        {
          "x": 15.6,
          "x": 11.6,
          "y": 5.2
        },
        {
          "x": 16.8,
          "x": 13.2,
          "y": 5.2
        },
        {
          "x": 17.6,
          "x": 14.4,
          "y": 5.2
        },
        {
          "x": 18.4,
          "y": 5.2
        },
        {
          "x": 18.8,
          "x": 15.6,
          "y": 5.2
        },
        {
          "x": 19.2,
          "x": 16.4,
          "y": 5.2
        },
        {
          "x": 19.2,
          "x": 17.2,
          "y": 5.2
        },
        {
          "x": 19.2,
          "x": 17.6,
          "y": 5.2
        },
        {
          "x": 19.2,
          "x": 18.4,
          "y": 5.2
        },
        {
          "x": 19.2,
          "x": 18.4,
          "y": 5.2
        },
        {
          "x": 19.2,
          "x": 18.8,
          "y": 5.2
        },
        {
@@ -462,75 +457,71 @@
        },
        {
          "width": 150,
          "height": 99.2
          "height": 102.8
        },
        {
          "width": 150,
          "height": 81.2
          "height": 91.2
        },
        {
          "width": 144,
          "height": 62.8
          "width": 149.2,
          "height": 78.8
        },
        {
          "width": 138,
          "height": 46.4
          "width": 145.2,
          "height": 66.4
        },
        {
          "width": 133.2,
          "height": 32
          "width": 141.2,
          "height": 54.8
        },
        {
          "width": 129.6,
          "height": 20.4
          "width": 137.6,
          "height": 44.4
        },
        {
          "width": 127.2,
          "height": 12
          "width": 134.4,
          "height": 35.2
        },
        {
          "width": 125.2,
          "height": 6.4
          "width": 131.6,
          "height": 26.4
        },
        {
          "width": 124,
          "height": 2.8
        },
        {
          "width": 123.2,
          "height": 0.4
          "width": 129.6,
          "height": 19.6
        },
        {
          "width": 122.4,
          "height": 0
          "width": 127.6,
          "height": 14.4
        },
        {
          "width": 122,
          "height": 0
          "width": 126.4,
          "height": 10.4
        },
        {
          "width": 122,
          "height": 0
          "width": 125.2,
          "height": 7.2
        },
        {
          "width": 122,
          "height": 0
          "width": 124,
          "height": 4.8
        },
        {
          "width": 122,
          "height": 0
          "width": 123.6,
          "height": 3.2
        },
        {
          "width": 122,
          "height": 0
          "width": 122.8,
          "height": 2
        },
        {
          "width": 122,
          "height": 0
          "width": 122.4,
          "height": 1.2
        },
        {
          "width": 122,
          "height": 0
          "width": 122.4,
          "height": 0.4
        },
        {
          "width": 122,
@@ -600,22 +591,21 @@
        1,
        1,
        1,
        0.99781144,
        0.87040234,
        0.6695792,
        0.48078007,
        0.33033127,
        0.22004372,
        0.14321749,
        0.09153093,
        0.057634596,
        0.035840217,
        0.022048427,
        0.013435689,
        0.008117776,
        0,
        0,
        0,
        1,
        1,
        1,
        0.9844751,
        0.8289564,
        0.6262902,
        0.44474912,
        0.30327561,
        0.20090407,
        0.13020064,
        0.08292485,
        0.052065734,
        0.032297794,
        0.019826554,
        0.01205862,
        0,
        0
      ]
+64 −94
Original line number Diff line number Diff line
@@ -58,10 +58,7 @@
    880,
    896,
    912,
    928,
    944,
    960,
    976
    928
  ],
  "features": [
    {
@@ -229,71 +226,59 @@
          "y": 5.2
        },
        {
          "x": 6.8,
          "y": 5.2
        },
        {
          "x": 10.4,
          "y": 5.2
        },
        {
          "x": 13.2,
          "y": 5.2
        },
        {
          "x": 15.2,
          "x": 5.2,
          "y": 5.2
        },
        {
          "x": 16.8,
          "x": 5.2,
          "y": 5.2
        },
        {
          "x": 17.6,
          "x": 7.2,
          "y": 5.2
        },
        {
          "x": 18.4,
          "x": 9.6,
          "y": 5.2
        },
        {
          "x": 18.8,
          "x": 11.6,
          "y": 5.2
        },
        {
          "x": 19.2,
          "x": 13.2,
          "y": 5.2
        },
        {
          "x": 19.2,
          "x": 14.8,
          "y": 5.2
        },
        {
          "x": 19.2,
          "x": 15.6,
          "y": 5.2
        },
        {
          "x": 19.2,
          "x": 16.8,
          "y": 5.2
        },
        {
          "x": 19.2,
          "x": 17.6,
          "y": 5.2
        },
        {
          "x": 19.2,
          "x": 18,
          "y": 5.2
        },
        {
          "x": 19.2,
          "x": 18.4,
          "y": 5.2
        },
        {
          "x": 19.2,
          "x": 18.8,
          "y": 5.2
        },
        {
          "x": 19.2,
          "x": 18.8,
          "y": 5.2
        },
        {
@@ -472,87 +457,75 @@
        },
        {
          "width": 150,
          "height": 147.2
          "height": 152.4
        },
        {
          "width": 150,
          "height": 122
          "height": 137.6
        },
        {
          "width": 150,
          "height": 95.2
        },
        {
          "width": 146.8,
          "height": 70.8
        },
        {
          "width": 139.6,
          "height": 50.8
          "height": 120.4
        },
        {
          "width": 134,
          "height": 34
        },
        {
          "width": 130,
          "height": 19.2
          "width": 150,
          "height": 102.8
        },
        {
          "width": 127.2,
          "height": 9.2
          "width": 150,
          "height": 85.6
        },
        {
          "width": 125.2,
          "height": 2.8
          "width": 146.4,
          "height": 70.4
        },
        {
          "width": 123.6,
          "height": 0
          "width": 141.6,
          "height": 56.8
        },
        {
          "width": 122.8,
          "height": 0
          "width": 137.6,
          "height": 44.8
        },
        {
          "width": 122.4,
          "height": 0
          "width": 134,
          "height": 34.4
        },
        {
          "width": 122,
          "height": 0
          "width": 131.2,
          "height": 25.2
        },
        {
          "width": 122,
          "height": 0
          "width": 129.2,
          "height": 18
        },
        {
          "width": 122,
          "height": 0
          "width": 127.2,
          "height": 12.8
        },
        {
          "width": 122,
          "height": 0
          "width": 125.6,
          "height": 8.8
        },
        {
          "width": 122,
          "height": 0
          "width": 124.8,
          "height": 5.6
        },
        {
          "width": 122,
          "height": 0
          "width": 124,
          "height": 3.6
        },
        {
          "width": 122,
          "height": 0
          "width": 123.2,
          "height": 2
        },
        {
          "width": 122,
          "height": 0
          "width": 122.8,
          "height": 1.2
        },
        {
          "width": 122,
          "height": 0
          "width": 122.4,
          "height": 0.4
        },
        {
          "width": 122,
@@ -619,25 +592,22 @@
        1,
        1,
        1,
        0.99979615,
        0.8860379,
        0.6869267,
        0.4955439,
        0.34154767,
        0.22803628,
        0.14868054,
        0.095156215,
        0.05998723,
        0.037340246,
        0.022991102,
        0.014020911,
        0.008477271,
        0,
        0,
        0,
        0,
        0,
        0
        1,
        1,
        1,
        1,
        0.9679595,
        0.7966402,
        0.5945783,
        0.41900647,
        0.284207,
        0.18753082,
        0.12116034,
        0.07697477,
        0.048229113,
        0.02986427,
        0.018303879,
        0.011116857
      ]
    }
  ]
Loading