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

Commit dfeebe5c authored by Alejandro Nijamkin's avatar Alejandro Nijamkin
Browse files

[flexiglass] Only animate lockscreen shortcuts when changing doze.

The CL adds logic to make sure that lockscreen shortcuts don't animate
when a Flexiglass scene transition is in progress.

Fix: 297403783
Test: unit tests added
Test: manually verified that switching scenes in Flexiglass does not
cause a vertical translate animation for the lockscreen shortcuts when
returning to the lockscreen scene
Test: manually verified that toggling AOD/doze on and off does animate
in Flexiglass and pre-Flexiglass

Change-Id: I8cdf4d5f038d4f7c4feb5c0e5c3f6e46f7925acf
parent 7ee8e80f
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -26,7 +26,6 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.motionEventSpy
import androidx.compose.ui.input.pointer.PointerEventPass
import androidx.compose.ui.input.pointer.motionEventSpy
import androidx.compose.ui.input.pointer.pointerInput
+28 −2
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 *
 */

@file:OptIn(ExperimentalCoroutinesApi::class)

package com.android.systemui.keyguard.domain.interactor

import android.app.StatusBarManager
@@ -42,10 +44,14 @@ import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.ScreenModel
import com.android.systemui.keyguard.shared.model.StatusBarState
import com.android.systemui.keyguard.shared.model.WakefulnessModel
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.shade.data.repository.ShadeRepository
import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import javax.inject.Provider
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.Flow
@@ -74,6 +80,7 @@ constructor(
    bouncerRepository: KeyguardBouncerRepository,
    configurationRepository: ConfigurationRepository,
    shadeRepository: ShadeRepository,
    sceneInteractorProvider: Provider<SceneInteractor>,
) {
    /** Position information for the shared notification container. */
    val sharedNotificationContainerPosition =
@@ -187,7 +194,7 @@ constructor(
        combine(isKeyguardShowing, isKeyguardOccluded) { showing, occluded -> showing && !occluded }

    /** Whether camera is launched over keyguard. */
    var isSecureCameraActive =
    val isSecureCameraActive: Flow<Boolean> by lazy {
        if (featureFlags.isEnabled(Flags.FACE_AUTH_REFACTOR)) {
            combine(
                    isKeyguardVisible,
@@ -204,6 +211,7 @@ constructor(
        } else {
            flowOf(false)
        }
    }

    /** The approximate location on the screen of the fingerprint sensor, if one is available. */
    val fingerprintSensorLocation: Flow<Point?> = repository.fingerprintSensorLocation
@@ -240,11 +248,29 @@ constructor(
        }

    /** Whether to animate the next doze mode transition. */
    val animateDozingTransitions: Flow<Boolean> = repository.animateBottomAreaDozingTransitions
    val animateDozingTransitions: Flow<Boolean> by lazy {
        if (featureFlags.isEnabled(Flags.SCENE_CONTAINER)) {
            sceneInteractorProvider
                .get()
                .transitioningTo
                .map { it == SceneKey.Lockscreen }
                .distinctUntilChanged()
                .flatMapLatest { isTransitioningToLockscreenScene ->
                    if (isTransitioningToLockscreenScene) {
                        flowOf(false)
                    } else {
                        repository.animateBottomAreaDozingTransitions
                    }
                }
        } else {
            repository.animateBottomAreaDozingTransitions
        }
    }

    fun dozeTransitionTo(vararg states: DozeStateModel): Flow<DozeTransitionModel> {
        return dozeTransitionModel.filter { states.contains(it.to) }
    }

    fun isKeyguardShowing(): Boolean {
        return repository.isKeyguardShowing()
    }
+2 −0
Original line number Diff line number Diff line
@@ -126,12 +126,14 @@ class ClockEventControllerTest : SysuiTestCase() {
        withDeps.featureFlags.apply {
            set(Flags.REGION_SAMPLING, false)
            set(Flags.DOZING_MIGRATION_1, false)
            set(Flags.FACE_AUTH_REFACTOR, false)
        }
        underTest =
            ClockEventController(
                withDeps.keyguardInteractor,
                KeyguardTransitionInteractorFactory.create(
                        scope = TestScope().backgroundScope,
                        featureFlags = withDeps.featureFlags,
                    )
                    .keyguardTransitionInteractor,
                broadcastDispatcher,
+6 −0
Original line number Diff line number Diff line
@@ -63,6 +63,7 @@ import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.settings.FakeSettings
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.UnconfinedTestDispatcher
import kotlinx.coroutines.test.runTest
@@ -174,12 +175,17 @@ class CustomizationProviderTest : SysuiTestCase() {
                set(Flags.REVAMPED_WALLPAPER_UI, true)
                set(Flags.WALLPAPER_FULLSCREEN_PREVIEW, true)
                set(Flags.FACE_AUTH_REFACTOR, true)
                set(Flags.SCENE_CONTAINER, false)
            }
        underTest.interactor =
            KeyguardQuickAffordanceInteractor(
                keyguardInteractor =
                    KeyguardInteractorFactory.create(
                            featureFlags = featureFlags,
                            sceneInteractor =
                                mock {
                                    whenever(transitioningTo).thenReturn(MutableStateFlow(null))
                                },
                        )
                        .keyguardInteractor,
                lockPatternUtils = lockPatternUtils,
+54 −9
Original line number Diff line number Diff line
@@ -15,6 +15,8 @@
 *
 */

@file:OptIn(ExperimentalCoroutinesApi::class)

package com.android.systemui.keyguard.domain.interactor

import android.app.StatusBarManager
@@ -27,11 +29,19 @@ import com.android.systemui.common.ui.data.repository.FakeConfigurationRepositor
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags.FACE_AUTH_REFACTOR
import com.android.systemui.flags.Flags.SCENE_CONTAINER
import com.android.systemui.keyguard.data.repository.FakeCommandQueue
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.shared.model.CameraLaunchSourceModel
import com.android.systemui.scene.SceneTestUtils
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.model.ObservableTransitionState
import com.android.systemui.scene.shared.model.SceneKey
import com.android.systemui.shade.data.repository.FakeShadeRepository
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.onCompletion
import kotlinx.coroutines.test.TestScope
import kotlinx.coroutines.test.runCurrent
@@ -54,25 +64,36 @@ class KeyguardInteractorTest : SysuiTestCase() {
    private lateinit var bouncerRepository: FakeKeyguardBouncerRepository
    private lateinit var configurationRepository: FakeConfigurationRepository
    private lateinit var shadeRepository: FakeShadeRepository
    private lateinit var sceneInteractor: SceneInteractor
    private lateinit var transitionState: MutableStateFlow<ObservableTransitionState>

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        featureFlags = FakeFeatureFlags().apply { set(FACE_AUTH_REFACTOR, true) }
        featureFlags =
            FakeFeatureFlags().apply {
                set(FACE_AUTH_REFACTOR, true)
                set(SCENE_CONTAINER, true)
            }
        commandQueue = FakeCommandQueue()
        testScope = TestScope()
        repository = FakeKeyguardRepository()
        val sceneTestUtils = SceneTestUtils(this)
        testScope = sceneTestUtils.testScope
        repository = sceneTestUtils.keyguardRepository
        bouncerRepository = FakeKeyguardBouncerRepository()
        configurationRepository = FakeConfigurationRepository()
        shadeRepository = FakeShadeRepository()
        sceneInteractor = sceneTestUtils.sceneInteractor()
        transitionState = MutableStateFlow(ObservableTransitionState.Idle(SceneKey.Gone))
        sceneInteractor.setTransitionState(transitionState)
        underTest =
            KeyguardInteractor(
                repository,
                commandQueue,
                featureFlags,
                bouncerRepository,
                configurationRepository,
                shadeRepository,
                repository = repository,
                commandQueue = commandQueue,
                featureFlags = featureFlags,
                bouncerRepository = bouncerRepository,
                configurationRepository = configurationRepository,
                shadeRepository = shadeRepository,
                sceneInteractorProvider = { sceneInteractor },
            )
    }

@@ -180,4 +201,28 @@ class KeyguardInteractorTest : SysuiTestCase() {

            assertThat(secureCameraActive()).isFalse()
        }

    @Test
    fun animationDozingTransitions() =
        testScope.runTest {
            val isAnimate by collectLastValue(underTest.animateDozingTransitions)

            underTest.setAnimateDozingTransitions(true)
            runCurrent()
            assertThat(isAnimate).isTrue()

            underTest.setAnimateDozingTransitions(false)
            runCurrent()
            assertThat(isAnimate).isFalse()

            underTest.setAnimateDozingTransitions(true)
            transitionState.value =
                ObservableTransitionState.Transition(
                    fromScene = SceneKey.Gone,
                    toScene = SceneKey.Lockscreen,
                    progress = flowOf(0f),
                )
            runCurrent()
            assertThat(isAnimate).isFalse()
        }
}
Loading