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

Commit 82565338 authored by Andreas Miko's avatar Andreas Miko
Browse files

Fix LightRevealScrim jank

The flag activates the light reveal animation for non-AOD scenarios.
However, there were performance regressions because depending on the
device model the screen would turn off slower or faster but sysui would
keep producing frames. This jank would not be visible but it causes
regression metrics to alarm. Depending on the device model the animation
might be cut off for the last couple frames which is acceptable given
that there is no easy deterministic way to coordinate these events.

Bug: b/316451404
Test: None
Flag: ACONFIG com.android.systemui.Flags.FLAG_LIGHT_REVEAL_MIGRATION DEVELOPMENT
Change-Id: Ia911975e3d7175177b65b456a88723d6b205c056
parent ccfa738a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -82,6 +82,7 @@ class LightRevealScrimInteractorTest : SysuiTestCase() {
                keyguardTransitionInteractor,
                fakeLightRevealScrimRepository,
                testScope.backgroundScope,
                mock(),
                mock()
            )
    }
+3 −2
Original line number Diff line number Diff line
@@ -140,8 +140,9 @@ constructor(
    override val revealAmount: Flow<Float> = callbackFlow {
        val updateListener =
            Animator.AnimatorUpdateListener {
                val value = (it as ValueAnimator).animatedValue
                trySend(value as Float)
                val value = (it as ValueAnimator).animatedValue as Float
                trySend(value)

                if (value <= 0.0f || value >= 1.0f) {
                    scrimLogger.d(TAG, "revealAmount", value)
                }
+14 −1
Original line number Diff line number Diff line
@@ -22,12 +22,15 @@ import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.data.repository.LightRevealScrimRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.power.shared.model.ScreenPowerState
import com.android.systemui.statusbar.LightRevealEffect
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.launch

@ExperimentalCoroutinesApi
@@ -39,6 +42,7 @@ constructor(
    private val lightRevealScrimRepository: LightRevealScrimRepository,
    @Application private val scope: CoroutineScope,
    private val scrimLogger: ScrimLogger,
    powerInteractor: PowerInteractor,
) {

    init {
@@ -73,7 +77,16 @@ constructor(
            lightRevealScrimRepository.revealEffect
        )

    val revealAmount = lightRevealScrimRepository.revealAmount
    val revealAmount =
        lightRevealScrimRepository.revealAmount.filter {
            // When the screen is off we do not want to keep producing frames as this is causing
            // (invisible) jank. However, we need to still pass through 1f and 0f to ensure that the
            // correct end states are respected even if the screen turned off (or was still off)
            // when the animation finished
            powerInteractor.screenPowerState.value != ScreenPowerState.SCREEN_OFF ||
                it == 1f ||
                it == 0f
        }

    companion object {

+8 −10
Original line number Diff line number Diff line
@@ -253,6 +253,8 @@ constructor(
    initialHeight: Int? = null
) : View(context, attrs) {

    private val logString = this::class.simpleName!! + "@" + hashCode()

    /** Listener that is called if the scrim's opaqueness changes */
    var isScrimOpaqueChangedListener: Consumer<Boolean>? = null

@@ -267,13 +269,13 @@ constructor(
            if (field != value) {
                field = value
                if (value <= 0.0f || value >= 1.0f) {
                    scrimLogger?.d(TAG, "revealAmount", "$value on ${logString()}")
                    scrimLogger?.d(TAG, "revealAmount", "$value on $logString")
                }
                revealEffect.setRevealAmountOnScrim(value, this)
                updateScrimOpaque()
                Trace.traceCounter(
                    Trace.TRACE_TAG_APP,
                    "light_reveal_amount",
                    "light_reveal_amount $logString",
                    (field * 100).toInt()
                )
                invalidate()
@@ -290,7 +292,7 @@ constructor(
                field = value

                revealEffect.setRevealAmountOnScrim(revealAmount, this)
                scrimLogger?.d(TAG, "revealEffect", "$value on ${logString()}")
                scrimLogger?.d(TAG, "revealEffect", "$value on $logString")
                invalidate()
            }
        }
@@ -350,7 +352,7 @@ constructor(
            if (field != value) {
                field = value
                isScrimOpaqueChangedListener?.accept(field)
                scrimLogger?.d(TAG, "isScrimOpaque", "$value on ${logString()}")
                scrimLogger?.d(TAG, "isScrimOpaque", "$value on $logString")
            }
        }

@@ -368,13 +370,13 @@ constructor(

    override fun setAlpha(alpha: Float) {
        super.setAlpha(alpha)
        scrimLogger?.d(TAG, "alpha", "$alpha on ${logString()}")
        scrimLogger?.d(TAG, "alpha", "$alpha on $logString")
        updateScrimOpaque()
    }

    override fun setVisibility(visibility: Int) {
        super.setVisibility(visibility)
        scrimLogger?.d(TAG, "visibility", "$visibility on ${logString()}")
        scrimLogger?.d(TAG, "visibility", "$visibility on $logString")
        updateScrimOpaque()
    }

@@ -467,8 +469,4 @@ constructor(
                PorterDuff.Mode.MULTIPLY
            )
    }

    private fun logString(): String {
        return this::class.simpleName!! + "@" + hashCode()
    }
}