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

Commit c9ce255f authored by Matt Pietal's avatar Matt Pietal
Browse files

Enable smoother burn-in adjustments on transition cancel

Using transitionValue() when a transition is canceled produces
a jump in values and a bad animation. Listening to transition
edges directly does not have that same effect, as it will use
the last real value emitted. To make sure values reset, also
listent to all transition to LOCKSCREEN.

Test: atest AodBurnInViewModelTest
Test: double-tap launch camera from AOD/LOCKSCREEN
Test: repeatedly unlock/lock with sidefps
Fixes: 336241173
Fixes: 369173324
Flag: EXEMPT bugfix
Change-Id: I084f06be7133d4c9e84d5983660f5086cee76337
parent cd1ea09d
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -44,6 +44,7 @@ import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.emptyFlow
import kotlinx.coroutines.test.runCurrent
import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Ignore
@@ -107,6 +108,7 @@ class AodBurnInViewModelTest : SysuiTestCase() {
    fun translationAndScale_whenNotDozing() =
        testScope.runTest {
            val movement by collectLastValue(underTest.movement)
            assertThat(movement?.translationX).isEqualTo(0)

            // Set to not dozing (on lockscreen)
            keyguardTransitionRepository.sendTransitionStep(
@@ -180,6 +182,7 @@ class AodBurnInViewModelTest : SysuiTestCase() {
        testScope.runTest {
            underTest.updateBurnInParams(burnInParameters.copy(minViewY = 100))
            val movement by collectLastValue(underTest.movement)
            assertThat(movement?.translationX).isEqualTo(0)

            // Set to dozing (on AOD)
            keyguardTransitionRepository.sendTransitionStep(
@@ -221,6 +224,7 @@ class AodBurnInViewModelTest : SysuiTestCase() {
        testScope.runTest {
            underTest.updateBurnInParams(burnInParameters.copy(minViewY = 100, topInset = 80))
            val movement by collectLastValue(underTest.movement)
            assertThat(movement?.translationX).isEqualTo(0)

            // Set to dozing (on AOD)
            keyguardTransitionRepository.sendTransitionStep(
@@ -263,6 +267,7 @@ class AodBurnInViewModelTest : SysuiTestCase() {
        testScope.runTest {
            underTest.updateBurnInParams(burnInParameters.copy(minViewY = 100, topInset = 80))
            val movement by collectLastValue(underTest.movement)
            assertThat(movement?.translationX).isEqualTo(0)

            // Set to dozing (on AOD)
            keyguardTransitionRepository.sendTransitionStep(
@@ -305,6 +310,7 @@ class AodBurnInViewModelTest : SysuiTestCase() {
            whenever(clockController.config.useAlternateSmartspaceAODTransition).thenReturn(true)

            val movement by collectLastValue(underTest.movement)
            assertThat(movement?.translationX).isEqualTo(0)

            // Set to dozing (on AOD)
            keyguardTransitionRepository.sendTransitionStep(
@@ -423,6 +429,7 @@ class AodBurnInViewModelTest : SysuiTestCase() {
                .thenReturn(if (isWeatherClock) true else false)

            val movement by collectLastValue(underTest.movement)
            assertThat(movement?.translationX).isEqualTo(0)

            // Set to dozing (on AOD)
            keyguardTransitionRepository.sendTransitionStep(
@@ -434,6 +441,7 @@ class AodBurnInViewModelTest : SysuiTestCase() {
                ),
                validateStep = false,
            )
            runCurrent()

            // Trigger a change to the burn-in model
            burnInFlow.value = BurnInModel(translationX = 20, translationY = 30, scale = 0.5f)
+11 −2
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.keyguard.domain.interactor

import android.animation.ValueAnimator
import android.util.Log
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.keyguard.KeyguardWmStateRefactor
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
@@ -33,7 +34,6 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.map
import com.android.app.tracing.coroutines.launchTraced as launch

/**
 * Each TransitionInteractor is responsible for determining under which conditions to notify
@@ -201,9 +201,18 @@ sealed class TransitionInteractor(
            scope.launch {
                keyguardInteractor.onCameraLaunchDetected.filterRelevantKeyguardState().collect {
                    if (!maybeHandleInsecurePowerGesture()) {
                        val lastStep = transitionInteractor.transitionState.value
                        val modeOnCanceled =
                            if (lastStep.to == KeyguardState.AOD) {
                                // Enabled smooth transition when double-tap camera cancels
                                // transition to AOD
                                TransitionModeOnCanceled.REVERSE
                            } else {
                                TransitionModeOnCanceled.RESET
                            }
                        startTransitionTo(
                            toState = KeyguardState.OCCLUDED,
                            modeOnCanceled = TransitionModeOnCanceled.RESET,
                            modeOnCanceled = modeOnCanceled,
                            ownerReason = "keyguardInteractor.onCameraLaunchDetected",
                        )
                    }
+14 −3
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.BurnInModel
import com.android.systemui.keyguard.shared.model.ClockSize
import com.android.systemui.keyguard.shared.model.Edge
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.ui.StateToValue
import com.android.systemui.res.R
@@ -42,8 +43,10 @@ import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.filter
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.flow.stateIn

@@ -164,9 +167,17 @@ constructor(

    private fun burnIn(params: BurnInParameters): Flow<BurnInModel> {
        return combine(
            keyguardTransitionInteractor.transitionValue(KeyguardState.AOD).map {
                Interpolators.FAST_OUT_SLOW_IN.getInterpolation(it)
            },
            merge(
                    keyguardTransitionInteractor.transition(Edge.create(to = KeyguardState.AOD)),
                    keyguardTransitionInteractor
                        .transition(Edge.create(from = KeyguardState.AOD))
                        .map { it.copy(value = 1f - it.value) },
                    keyguardTransitionInteractor
                        .transition(Edge.create(to = KeyguardState.LOCKSCREEN))
                        .filter { it.from != KeyguardState.AOD }
                        .map { it.copy(value = 0f) },
                )
                .map { Interpolators.FAST_OUT_SLOW_IN.getInterpolation(it.value) },
            burnInInteractor.burnIn(
                xDimenResourceId = R.dimen.burn_in_prevention_offset_x,
                yDimenResourceId = R.dimen.burn_in_prevention_offset_y,