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

Commit 75128c1c authored by Matt Pietal's avatar Matt Pietal
Browse files

Support keyguard lock timeout and security NONE

When waking up from AOD or DOZING, check if keyguard is showing.
KeyguardViewMediator is still responsible for this logic and
will not show keyguard if there is a lock timeout or security
is set to NONE.

This also fixes a race condition with DOZING that could result
in going to LOCKSCREEN instead of GONE.

Fixes: 327606987
Fixes: 326988246
Fixes: 327717534
Test: atest AodToGoneTransitionViewModelTest
DozingToGoneTransitionViewModelTest
Flag: ACONFIG com.android.systemui.migrate_clocks_to_blueprint
TEAMFOOD

Change-Id: I9f7976760292be5d5765e49021e0d579a6250092
parent 4c56cf75
Loading
Loading
Loading
Loading
+19 −0
Original line number Diff line number Diff line
@@ -41,6 +41,25 @@ class AodToGoneTransitionViewModelTest : SysuiTestCase() {
    val repository = kosmos.fakeKeyguardTransitionRepository
    val underTest = kosmos.aodToGoneTransitionViewModel

    @Test
    fun lockscreenAlpha() =
        testScope.runTest {
            val viewState = ViewStateAccessor(alpha = { 0.5f })
            val alpha by collectValues(underTest.lockscreenAlpha(viewState))

            repository.sendTransitionSteps(
                from = KeyguardState.AOD,
                to = KeyguardState.GONE,
                testScope
            )

            assertThat(alpha[0]).isEqualTo(0.5f)
            // Fades out just prior to halfway
            assertThat(alpha[1]).isEqualTo(0f)
            // Must finish at 0
            assertThat(alpha[2]).isEqualTo(0f)
        }

    @Test
    fun deviceEntryParentViewHides() =
        testScope.runTest {
+19 −0
Original line number Diff line number Diff line
@@ -50,6 +50,25 @@ class DozingToGoneTransitionViewModelTest : SysuiTestCase() {
        underTest = kosmos.dozingToGoneTransitionViewModel
    }

    @Test
    fun lockscreenAlpha() =
        testScope.runTest {
            val viewState = ViewStateAccessor(alpha = { 0.6f })
            val alpha by collectValues(underTest.lockscreenAlpha(viewState))

            keyguardTransitionRepository.sendTransitionSteps(
                from = KeyguardState.DOZING,
                to = KeyguardState.GONE,
                testScope
            )

            assertThat(alpha[0]).isEqualTo(0.6f)
            // Fades out just prior to halfway
            assertThat(alpha[1]).isEqualTo(0f)
            // Must finish at 0
            assertThat(alpha[2]).isEqualTo(0f)
        }

    @Test
    fun deviceEntryParentViewDisappear() =
        testScope.runTest {
+41 −16
Original line number Diff line number Diff line
@@ -27,12 +27,14 @@ import com.android.systemui.keyguard.shared.model.BiometricUnlockModel.Companion
import com.android.systemui.keyguard.shared.model.DozeStateModel
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.util.kotlin.Utils.Companion.sample
import com.android.systemui.util.kotlin.sample
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.launch

@SysUISingleton
@@ -45,6 +47,7 @@ constructor(
    @Background bgDispatcher: CoroutineDispatcher,
    @Main mainDispatcher: CoroutineDispatcher,
    private val keyguardInteractor: KeyguardInteractor,
    private val powerInteractor: PowerInteractor,
) :
    TransitionInteractor(
        fromState = KeyguardState.AOD,
@@ -68,9 +71,10 @@ constructor(
     */
    private fun listenForAodToOccluded() {
        scope.launch {
            keyguardInteractor.isKeyguardOccluded.sample(startedKeyguardState, ::Pair).collect {
                (isOccluded, startedKeyguardState) ->
                if (isOccluded && startedKeyguardState == KeyguardState.AOD) {
            keyguardInteractor.isKeyguardOccluded
                .sample(startedKeyguardTransitionStep, ::Pair)
                .collect { (isOccluded, lastStartedStep) ->
                    if (isOccluded && lastStartedStep.to == KeyguardState.AOD) {
                        startTransitionTo(
                            toState = KeyguardState.OCCLUDED,
                            modeOnCanceled = TransitionModeOnCanceled.RESET
@@ -85,15 +89,18 @@ constructor(
            keyguardInteractor
                .dozeTransitionTo(DozeStateModel.FINISH)
                .sample(
                    keyguardInteractor.isKeyguardShowing,
                    startedKeyguardTransitionStep,
                    keyguardInteractor.isKeyguardOccluded,
                    keyguardInteractor.biometricUnlockState,
                )
                .collect { (_, lastStartedStep, occluded, biometricUnlockState) ->
                .collect { (_, isKeyguardShowing, lastStartedStep, occluded, biometricUnlockState)
                    ->
                    if (
                        lastStartedStep.to == KeyguardState.AOD &&
                            !occluded &&
                            !isWakeAndUnlock(biometricUnlockState)
                            !isWakeAndUnlock(biometricUnlockState) &&
                            isKeyguardShowing
                    ) {
                        val modeOnCanceled =
                            if (lastStartedStep.from == KeyguardState.LOCKSCREEN) {
@@ -134,10 +141,28 @@ constructor(
        }

        scope.launch {
            keyguardInteractor.biometricUnlockState.sample(finishedKeyguardState, ::Pair).collect {
                (biometricUnlockState, keyguardState) ->
            powerInteractor.isAwake
                .debounce(50L)
                .sample(
                    keyguardInteractor.biometricUnlockState,
                    startedKeyguardTransitionStep,
                    keyguardInteractor.isKeyguardShowing,
                    keyguardInteractor.isKeyguardDismissible,
                )
                .collect {
                    (
                        isAwake,
                        biometricUnlockState,
                        lastStartedTransitionStep,
                        isKeyguardShowing,
                        isKeyguardDismissible) ->
                    KeyguardWmStateRefactor.assertInLegacyMode()
                if (keyguardState == KeyguardState.AOD && isWakeAndUnlock(biometricUnlockState)) {
                    if (
                        isAwake &&
                            lastStartedTransitionStep.to == KeyguardState.AOD &&
                            (isWakeAndUnlock(biometricUnlockState) ||
                                (!isKeyguardShowing && isKeyguardDismissible))
                    ) {
                        startTransitionTo(KeyguardState.GONE)
                    }
                }
+35 −39
Original line number Diff line number Diff line
@@ -26,13 +26,12 @@ import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositor
import com.android.systemui.keyguard.shared.model.BiometricUnlockModel.Companion.isWakeAndUnlock
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.util.kotlin.Utils.Companion.toQuad
import com.android.systemui.util.kotlin.sample
import com.android.systemui.util.kotlin.Utils.Companion.sample
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.debounce
import kotlinx.coroutines.launch

@SysUISingleton
@@ -56,27 +55,40 @@ constructor(
    ) {

    override fun start() {
        listenForDozingToLockscreenHubOrOccluded()
        listenForDozingToGone()
        listenForDozingToAny()
        listenForTransitionToCamera(scope, keyguardInteractor)
    }

    private fun listenForDozingToLockscreenHubOrOccluded() {
    private fun listenForDozingToAny() {
        scope.launch {
            powerInteractor.isAwake
                .debounce(50L)
                .sample(
                    combine(
                    keyguardInteractor.biometricUnlockState,
                    startedKeyguardTransitionStep,
                    keyguardInteractor.isKeyguardOccluded,
                    communalInteractor.isIdleOnCommunal,
                        ::Triple
                    ),
                    ::toQuad
                    keyguardInteractor.isKeyguardShowing,
                    keyguardInteractor.isKeyguardDismissible,
                )
                .collect { (isAwake, lastStartedTransition, occluded, isIdleOnCommunal) ->
                    if (isAwake && lastStartedTransition.to == KeyguardState.DOZING) {
                .collect {
                    (
                        isAwake,
                        biometricUnlockState,
                        lastStartedTransition,
                        occluded,
                        isIdleOnCommunal,
                        isKeyguardShowing,
                        isKeyguardDismissible) ->
                    if (!(isAwake && lastStartedTransition.to == KeyguardState.DOZING)) {
                        return@collect
                    }
                    startTransitionTo(
                            if (occluded) {
                        if (isWakeAndUnlock(biometricUnlockState)) {
                            KeyguardState.GONE
                        } else if (isKeyguardDismissible && !isKeyguardShowing) {
                            KeyguardState.GONE
                        } else if (occluded) {
                            KeyguardState.OCCLUDED
                        } else if (isIdleOnCommunal) {
                            KeyguardState.GLANCEABLE_HUB
@@ -87,22 +99,6 @@ constructor(
                }
        }
    }
    }

    private fun listenForDozingToGone() {
        scope.launch {
            keyguardInteractor.biometricUnlockState
                .sample(startedKeyguardTransitionStep, ::Pair)
                .collect { (biometricUnlockState, lastStartedTransition) ->
                    if (
                        lastStartedTransition.to == KeyguardState.DOZING &&
                            isWakeAndUnlock(biometricUnlockState)
                    ) {
                        startTransitionTo(KeyguardState.GONE)
                    }
                }
        }
    }

    override fun getDefaultAnimatorForTransitionsToState(toState: KeyguardState): ValueAnimator {
        return ValueAnimator().apply {
+13 −0
Original line number Diff line number Diff line
@@ -16,13 +16,16 @@

package com.android.systemui.keyguard.ui.viewmodel

import android.util.MathUtils
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.keyguard.domain.interactor.FromAodTransitionInteractor
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.ui.KeyguardTransitionAnimationFlow
import com.android.systemui.keyguard.ui.transitions.DeviceEntryIconTransition
import javax.inject.Inject
import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow

/** Breaks down AOD->GONE transition into discrete steps for corresponding views to consume. */
@ExperimentalCoroutinesApi
@@ -40,5 +43,15 @@ constructor(
            to = KeyguardState.GONE,
        )

    fun lockscreenAlpha(viewState: ViewStateAccessor): Flow<Float> {
        var startAlpha = 1f
        return transitionAnimation.sharedFlow(
            duration = 200.milliseconds,
            onStart = { startAlpha = viewState.alpha() },
            onStep = { MathUtils.lerp(startAlpha, 0f, it) },
            onFinish = { 0f },
        )
    }

    override val deviceEntryParentViewAlpha = transitionAnimation.immediatelyTransitionTo(0f)
}
Loading