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

Commit 0cb8c7fc authored by Josh Tsuji's avatar Josh Tsuji Committed by Android (Google) Code Review
Browse files

Merge "Add KeyguardTransitionBootInteractor." into main

parents d24e1edf 7c450c4a
Loading
Loading
Loading
Loading
+7 −1
Original line number Diff line number Diff line
@@ -235,7 +235,13 @@ class KeyguardTransitionInteractorTest : SysuiTestCase() {
                .isEqualTo(
                    listOf(
                        // The initial transition will also get sent when collect started
                        TransitionStep(OFF, LOCKSCREEN, 0f, STARTED),
                        TransitionStep(
                            OFF,
                            LOCKSCREEN,
                            0f,
                            STARTED,
                            ownerName = "KeyguardTransitionRepository(boot)"
                        ),
                        steps[0],
                        steps[3],
                        steps[6]
+9 −0
Original line number Diff line number Diff line
@@ -239,6 +239,15 @@ constructor(
            authenticationInteractor.getAuthenticationMethod().isSecure
    }

    /**
     * Whether the lockscreen is enabled for the current user. This is `true` whenever the user has
     * chosen any secure authentication method and even if they set the lockscreen to be dismissed
     * when the user swipes on it.
     */
    suspend fun isLockscreenEnabled(): Boolean {
        return repository.isLockscreenEnabled()
    }

    /**
     * Whether lockscreen bypass is enabled. When enabled, the lockscreen will be automatically
     * dismissed once the authentication challenge is completed. For example, completing a biometric
+39 −29
Original line number Diff line number Diff line
@@ -88,6 +88,12 @@ interface KeyguardTransitionRepository {
     */
    suspend fun startTransition(info: TransitionInfo): UUID?

    /**
     * Emits STARTED and FINISHED transition steps to the given state. This is used during boot to
     * seed the repository with the appropriate initial state.
     */
    suspend fun emitInitialStepsFromOff(to: KeyguardState)

    /**
     * Allows manual control of a transition. When calling [startTransition], the consumer must pass
     * in a null animator. In return, it will get a unique [UUID] that will be validated to allow
@@ -141,9 +147,17 @@ constructor(
    private var updateTransitionId: UUID? = null

    init {
        // Seed with transitions signaling a boot into lockscreen state. If updating this, please
        // also update FakeKeyguardTransitionRepository.
        initialTransitionSteps.forEach(::emitTransition)
        // Start with a FINISHED transition in OFF. KeyguardBootInteractor will transition from OFF
        // to either GONE or LOCKSCREEN once we're booted up and can determine which state we should
        // start in.
        emitTransition(
            TransitionStep(
                KeyguardState.OFF,
                KeyguardState.OFF,
                1f,
                TransitionState.FINISHED,
            )
        )
    }

    override suspend fun startTransition(info: TransitionInfo): UUID? {
@@ -251,6 +265,28 @@ constructor(
        lastStep = nextStep
    }

    override suspend fun emitInitialStepsFromOff(to: KeyguardState) {
        emitTransition(
            TransitionStep(
                KeyguardState.OFF,
                to,
                0f,
                TransitionState.STARTED,
                ownerName = "KeyguardTransitionRepository(boot)",
            )
        )

        emitTransition(
            TransitionStep(
                KeyguardState.OFF,
                to,
                1f,
                TransitionState.FINISHED,
                ownerName = "KeyguardTransitionRepository(boot)",
            ),
        )
    }

    private fun logAndTrace(step: TransitionStep, isManual: Boolean) {
        if (step.transitionState == TransitionState.RUNNING) {
            return
@@ -271,31 +307,5 @@ constructor(

    companion object {
        private const val TAG = "KeyguardTransitionRepository"

        /**
         * Transition steps to seed the repository with, so that all of the transition interactor
         * flows emit reasonable initial values.
         */
        val initialTransitionSteps: List<TransitionStep> =
            listOf(
                TransitionStep(
                    KeyguardState.OFF,
                    KeyguardState.OFF,
                    1f,
                    TransitionState.FINISHED,
                ),
                TransitionStep(
                    KeyguardState.OFF,
                    KeyguardState.LOCKSCREEN,
                    0f,
                    TransitionState.STARTED,
                ),
                TransitionStep(
                    KeyguardState.OFF,
                    KeyguardState.LOCKSCREEN,
                    1f,
                    TransitionState.FINISHED,
                ),
            )
    }
}
+5 −5
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ constructor(
        listenForTransitionToCamera(scope, keyguardInteractor)
    }

    private val canDismissLockScreen: Flow<Boolean> =
    private val canTransitionToGoneOnWake: Flow<Boolean> =
        combine(
            keyguardInteractor.isKeyguardShowing,
            keyguardInteractor.isKeyguardDismissible,
@@ -87,7 +87,7 @@ constructor(
                    keyguardInteractor.biometricUnlockState,
                    keyguardInteractor.isKeyguardOccluded,
                    communalInteractor.isIdleOnCommunal,
                    canDismissLockScreen,
                    canTransitionToGoneOnWake,
                    keyguardInteractor.primaryBouncerShowing,
                )
                .collect {
@@ -96,12 +96,12 @@ constructor(
                        biometricUnlockState,
                        occluded,
                        isIdleOnCommunal,
                        canDismissLockScreen,
                        canTransitionToGoneOnWake,
                        primaryBouncerShowing) ->
                    startTransitionTo(
                        if (isWakeAndUnlock(biometricUnlockState.mode)) {
                            KeyguardState.GONE
                        } else if (canDismissLockScreen) {
                        } else if (canTransitionToGoneOnWake) {
                            KeyguardState.GONE
                        } else if (primaryBouncerShowing) {
                            KeyguardState.PRIMARY_BOUNCER
@@ -129,7 +129,7 @@ constructor(
                .sample(
                    communalInteractor.isIdleOnCommunal,
                    keyguardInteractor.biometricUnlockState,
                    canDismissLockScreen,
                    canTransitionToGoneOnWake,
                    keyguardInteractor.primaryBouncerShowing,
                )
                .collect {
+81 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2024 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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

import android.util.Log
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch

/** Handles initialization of the KeyguardTransitionRepository on boot. */
@SysUISingleton
class KeyguardTransitionBootInteractor
@Inject
constructor(
    @Application val scope: CoroutineScope,
    val deviceEntryInteractor: DeviceEntryInteractor,
    val deviceProvisioningInteractor: DeviceProvisioningInteractor,
    val keyguardTransitionInteractor: KeyguardTransitionInteractor,
    val repository: KeyguardTransitionRepository,
) : CoreStartable {

    /**
     * Whether the lockscreen should be showing when the device starts up for the first time. If not
     * then we'll seed the repository with a transition from OFF -> GONE.
     */
    @OptIn(ExperimentalCoroutinesApi::class)
    private val showLockscreenOnBoot =
        deviceProvisioningInteractor.isDeviceProvisioned.map { provisioned ->
            (provisioned || deviceEntryInteractor.isAuthenticationRequired()) &&
                deviceEntryInteractor.isLockscreenEnabled()
        }

    override fun start() {
        scope.launch {
            val state =
                if (showLockscreenOnBoot.first()) {
                    KeyguardState.LOCKSCREEN
                } else {
                    KeyguardState.GONE
                }

            if (
                keyguardTransitionInteractor.currentTransitionInfoInternal.value.from !=
                    KeyguardState.OFF
            ) {
                Log.e(
                    "KeyguardTransitionInteractor",
                    "showLockscreenOnBoot emitted, but we've already " +
                        "transitioned to a state other than OFF. We'll respect that " +
                        "transition, but this should not happen."
                )
            } else {
                repository.emitInitialStepsFromOff(state)
            }
        }
    }
}
Loading