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

Commit 38ecd007 authored by Michael Mikhail's avatar Michael Mikhail Committed by Android (Google) Code Review
Browse files

Merge "Use runnable for drawer update instead of endListener" into main

parents 1738c8a4 b2b1f0e0
Loading
Loading
Loading
Loading
+33 −41
Original line number Diff line number Diff line
@@ -24,7 +24,6 @@ import android.widget.ImageButton
import androidx.annotation.LayoutRes
import androidx.compose.ui.util.fastForEachIndexed
import androidx.constraintlayout.motion.widget.MotionLayout
import androidx.dynamicanimation.animation.DynamicAnimation
import androidx.dynamicanimation.animation.FloatValueHolder
import androidx.dynamicanimation.animation.SpringAnimation
import androidx.dynamicanimation.animation.SpringForce
@@ -44,13 +43,16 @@ import com.android.systemui.volume.dialog.ui.utils.suspendAnimate
import javax.inject.Inject
import kotlin.properties.Delegates
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.launch

private const val CLOSE_DRAWER_DELAY = 300L

@OptIn(ExperimentalCoroutinesApi::class)
@VolumeDialogScope
class VolumeDialogRingerViewBinder
@Inject
@@ -95,7 +97,7 @@ constructor(private val viewModel: VolumeDialogRingerDrawerViewModel) {
        volumeDialogBackgroundView.background = volumeDialogBackgroundView.background.mutate()

        viewModel.ringerViewModel
            .onEach { ringerState ->
            .mapLatest { ringerState ->
                when (ringerState) {
                    is RingerViewModelState.Available -> {
                        val uiModel = ringerState.uiModel
@@ -221,15 +223,6 @@ constructor(private val viewModel: VolumeDialogRingerDrawerViewModel) {
            val unselectedButton =
                getChildAt(count - previousIndex - 1)
                    .requireViewById<ImageButton>(R.id.volume_drawer_button)

            // On roundness animation end.
            val roundnessAnimationEndListener =
                DynamicAnimation.OnAnimationEndListener { _, _, _, _ ->
                    postDelayed(
                        { bindButtons(viewModel, uiModel, onAnimationEnd, isAnimated = true) },
                        CLOSE_DRAWER_DELAY,
                    )
                }
            // We only need to execute on roundness animation end and volume dialog background
            // progress update once because these changes should be applied once on volume dialog
            // background and ringer drawer views.
@@ -242,7 +235,6 @@ constructor(private val viewModel: VolumeDialogRingerDrawerViewModel) {
                    } else {
                        { _, _ -> }
                    },
                    roundnessAnimationEndListener,
                )
            }
            val unselectedCornerRadius =
@@ -257,6 +249,12 @@ constructor(private val viewModel: VolumeDialogRingerDrawerViewModel) {
                    },
                )
            }
            coroutineScope {
                launch {
                    delay(CLOSE_DRAWER_DELAY)
                    bindButtons(viewModel, uiModel, onAnimationEnd, isAnimated = true)
                }
            }
        } else {
            bindButtons(viewModel, uiModel, onAnimationEnd)
        }
@@ -348,7 +346,6 @@ constructor(private val viewModel: VolumeDialogRingerDrawerViewModel) {
    private suspend fun ImageButton.animateTo(
        ringerButtonUiModel: RingerButtonUiModel,
        onProgressChanged: (Float, Boolean) -> Unit = { _, _ -> },
        roundnessAnimationEndListener: DynamicAnimation.OnAnimationEndListener? = null,
    ) {
        val roundnessAnimation =
            SpringAnimation(FloatValueHolder(0F)).setSpring(roundnessSpringForce)
@@ -356,14 +353,9 @@ constructor(private val viewModel: VolumeDialogRingerDrawerViewModel) {
        val radius = (background as GradientDrawable).cornerRadius
        val cornerRadiusDiff =
            ringerButtonUiModel.cornerRadius - (background as GradientDrawable).cornerRadius
        val roundnessAnimationUpdateListener =
            DynamicAnimation.OnAnimationUpdateListener { _, value, _ ->
                onProgressChanged(value, cornerRadiusDiff > 0F)
                (background as GradientDrawable).cornerRadius = radius + value * cornerRadiusDiff
                background.invalidateSelf()
            }
        val colorAnimationUpdateListener =
            DynamicAnimation.OnAnimationUpdateListener { _, value, _ ->
        coroutineScope {
            launch {
                colorAnimation.suspendAnimate { value ->
                    val currentIconColor =
                        rgbEvaluator.evaluate(
                            value.coerceIn(0F, 1F),
@@ -381,12 +373,12 @@ constructor(private val viewModel: VolumeDialogRingerDrawerViewModel) {
                    background.invalidateSelf()
                    setColorFilter(currentIconColor)
                }
        coroutineScope {
            launch { colorAnimation.suspendAnimate(colorAnimationUpdateListener) }
            roundnessAnimation.suspendAnimate(
                roundnessAnimationUpdateListener,
                roundnessAnimationEndListener,
            )
            }
            roundnessAnimation.suspendAnimate { value ->
                onProgressChanged(value, cornerRadiusDiff > 0F)
                (background as GradientDrawable).cornerRadius = radius + value * cornerRadiusDiff
                background.invalidateSelf()
            }
        }
    }

+14 −15
Original line number Diff line number Diff line
@@ -87,19 +87,18 @@ suspend fun <T> ValueAnimator.suspendAnimate(onValueChanged: (T) -> Unit) {
 * Starts spring animation and suspends until it's finished. Cancels the animation if the running
 * coroutine is cancelled.
 */
suspend fun SpringAnimation.suspendAnimate(
    animationUpdateListener: DynamicAnimation.OnAnimationUpdateListener? = null,
    animationEndListener: DynamicAnimation.OnAnimationEndListener? = null,
) = suspendCancellableCoroutine { continuation ->
    animationUpdateListener?.let(::addUpdateListener)
    addEndListener { animation, canceled, value, velocity ->
        continuation.resumeIfCan(Unit)
        animationEndListener?.onAnimationEnd(animation, canceled, value, velocity)
    }
suspend fun SpringAnimation.suspendAnimate(onAnimationUpdate: (Float) -> Unit) =
    suspendCancellableCoroutine { continuation ->
        val updateListener =
            DynamicAnimation.OnAnimationUpdateListener { _, value, _ -> onAnimationUpdate(value) }
        val endListener =
            DynamicAnimation.OnAnimationEndListener { _, _, _, _ -> continuation.resumeIfCan(Unit) }
        addUpdateListener(updateListener)
        addEndListener(endListener)
        animateToFinalPosition(1F)
        continuation.invokeOnCancellation {
        animationUpdateListener?.let(::removeUpdateListener)
        animationEndListener?.let(::removeEndListener)
            removeUpdateListener(updateListener)
            removeEndListener(endListener)
            cancel()
        }
    }