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

Commit 2c414a80 authored by Lucas Dupin's avatar Lucas Dupin
Browse files

Annotate chip animation for jank

Added begin/end annotations to AnimatedActionBackgroundDrawable, so we
can keep track of performance or dropped frames in the field

Bug: 383567383
Test: ./record_android_trace -c syshealth.pbtx
Flag: com.android.systemui.notification_animated_actions_treatment
Change-Id: I738071fe03b27a09bc1d86018026e965426c4188
parent fb2a0e97
Loading
Loading
Loading
Loading
+45 −5
Original line number Diff line number Diff line
@@ -16,6 +16,8 @@

package com.android.systemui.statusbar.notification.row

import android.animation.Animator
import android.animation.AnimatorListenerAdapter
import android.animation.ValueAnimator
import android.content.Context
import android.content.res.ColorStateList
@@ -37,21 +39,41 @@ import androidx.core.graphics.ColorUtils
import com.android.systemui.res.R
import com.android.wm.shell.shared.animation.Interpolators

class AnimatedActionBackgroundDrawable(context: Context) :
class AnimatedActionBackgroundDrawable(
    context: Context,
    onAnimationStarted: () -> Unit,
    onAnimationEnded: () -> Unit,
    onAnimationCancelled: () -> Unit,
) :
    RippleDrawable(
        ContextCompat.getColorStateList(context, R.color.notification_ripple_untinted_color)
            ?: ColorStateList.valueOf(Color.TRANSPARENT),
        createBaseDrawable(context),
        createBaseDrawable(context, onAnimationStarted, onAnimationEnded, onAnimationCancelled),
        null,
    ) {
    companion object {
        private fun createBaseDrawable(context: Context): Drawable {
            return BaseBackgroundDrawable(context)
        private fun createBaseDrawable(
            context: Context,
            onAnimationStarted: () -> Unit,
            onAnimationEnded: () -> Unit,
            onAnimationCancelled: () -> Unit,
        ): Drawable {
            return BaseBackgroundDrawable(
                context,
                onAnimationStarted,
                onAnimationEnded,
                onAnimationCancelled,
            )
        }
    }
}

class BaseBackgroundDrawable(context: Context) : Drawable() {
class BaseBackgroundDrawable(
    context: Context,
    onAnimationStarted: () -> Unit,
    onAnimationEnded: () -> Unit,
    onAnimationCancelled: () -> Unit,
) : Drawable() {

    private val cornerRadius =
        context.resources
@@ -113,6 +135,17 @@ class BaseBackgroundDrawable(context: Context) : Drawable() {
                startDelay = 1000
                interpolator = Interpolators.LINEAR
                repeatCount = 0
                addListener(
                    object : AnimatorListenerAdapter() {
                        override fun onAnimationEnd(animation: Animator) {
                            onAnimationEnded()
                        }

                        override fun onAnimationCancel(animation: Animator) {
                            onAnimationCancelled()
                        }
                    }
                )
                addUpdateListener { animator ->
                    val animatedValue = animator.animatedValue as Float
                    rotationAngle = 20f + animatedValue * 360f // Rotate in a spiral
@@ -130,6 +163,13 @@ class BaseBackgroundDrawable(context: Context) : Drawable() {
                    solidAlpha = (progress * 255).toInt() // Fade in color
                    invalidateSelf()
                }
                addListener(
                    object : AnimatorListenerAdapter() {
                        override fun onAnimationStart(animation: Animator) {
                            onAnimationStarted()
                        }
                    }
                )
                start()
            }
    }
+20 −6
Original line number Diff line number Diff line
@@ -20,17 +20,31 @@ import android.annotation.SuppressLint
import android.content.Context
import android.util.AttributeSet
import android.widget.Button
import com.android.internal.jank.Cuj
import com.android.internal.jank.InteractionJankMonitor

/**
 * Custom Button for Animated Action Button, which includes the custom background and foreground.
 */
@SuppressLint("AppCompatCustomView")
class AnimatedActionButton @JvmOverloads constructor(
    context: Context,
    attrs: AttributeSet? = null,
    defStyleAttr: Int = 0,
) : Button(context, attrs, defStyleAttr) {
class AnimatedActionButton
@JvmOverloads
constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
    Button(context, attrs, defStyleAttr) {
    init {
        background = AnimatedActionBackgroundDrawable(context)
        val interactionJankMonitor = InteractionJankMonitor.getInstance()
        background =
            AnimatedActionBackgroundDrawable(
                context = context,
                onAnimationStarted = {
                    interactionJankMonitor.begin(this, Cuj.CUJ_NOTIFICATIONS_ANIMATED_ACTION)
                },
                onAnimationEnded = {
                    interactionJankMonitor.end(Cuj.CUJ_NOTIFICATIONS_ANIMATED_ACTION)
                },
                onAnimationCancelled = {
                    interactionJankMonitor.cancel(Cuj.CUJ_NOTIFICATIONS_ANIMATED_ACTION)
                },
            )
    }
}