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

Commit 2608607c authored by Leon Masopust's avatar Leon Masopust
Browse files

[flexiglass] Snap to Scenes.Gone after boot

As soon as the SceneContainer is initialized, the view model checks
if the lock screen should be shown as initial scene and if not will
initiate a switch to Scenes.Gone. This is making sure that the lock
screen will no longer be shown after boot when no screen lock is
set. Setting the screen lock to "Swipe to enter" will make the
lockscreen appear on boot as expected.

Test: manually tested boot, show/hide shade, open/close keyguard,
switch users, create new user and go through SuW with flexiglass on
and off using different screen lock options
Flag: com.android.systemui.scene_container
Bug: 412925277. 360372242

Change-Id: Id70f101a059bfdd26f112d532af8fdbfcde2ea51
parent 44d5d407
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -144,6 +144,8 @@ fun SceneContainer(
            deferTransitionProgress = true,
        )

    LaunchedEffect(Unit) { viewModel.onInitialComposition() }

    DisposableEffect(state) {
        val dataSource = SceneTransitionLayoutDataSource(state, coroutineScope)
        dataSourceDelegator.setDelegate(dataSource)
+6 −30
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.systemui.keyguard.domain.interactor

import android.util.Log
import com.android.app.tracing.coroutines.launchTraced as launch
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
@@ -24,14 +25,11 @@ import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepositor
import com.android.systemui.keyguard.shared.model.KeyguardState.GONE
import com.android.systemui.keyguard.shared.model.KeyguardState.LOCKSCREEN
import com.android.systemui.keyguard.shared.model.KeyguardState.OFF
import com.android.systemui.scene.domain.interactor.OnBootTransitionInteractor
import com.android.systemui.scene.shared.flag.SceneContainerFlag
import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.first
import kotlinx.coroutines.flow.map
import com.android.app.tracing.coroutines.launchTraced as launch

/** Handles initialization of the KeyguardTransitionRepository on boot. */
@SysUISingleton
@@ -43,45 +41,23 @@ constructor(
    val deviceProvisioningInteractor: DeviceProvisioningInteractor,
    val keyguardTransitionInteractor: KeyguardTransitionInteractor,
    val internalTransitionInteractor: InternalKeyguardTransitionInteractor,
    val onBootTransitionInteractor: OnBootTransitionInteractor,
    val repository: KeyguardTransitionRepository,
) {

    /**
     * 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.
     */
    private val showLockscreenOnBoot: Flow<Boolean> by lazy {
        deviceProvisioningInteractor.isDeviceProvisioned.map { provisioned ->
            (provisioned || deviceEntryInteractor.isAuthenticationRequired()) &&
                deviceEntryInteractor.isLockscreenEnabled()
        }
    }

    fun start() {
        scope.launch {
            if (internalTransitionInteractor.currentTransitionInfoInternal().from != OFF) {
                Log.e(
                    "KeyguardTransitionInteractor",
                    "showLockscreenOnBoot emitted, but we've already " +
                        "transitioned to a state other than OFF. We'll respect that " +
                    "KeyguardTransitionBootInteractor",
                    "We've already transitioned to a state other than OFF. We'll respect that " +
                        "transition, but this should not happen.",
                )
            } else {
                if (SceneContainerFlag.isEnabled) {
                    // TODO(b/360372242): Some part of the transition implemented for flag off is
                    //  missing here. There are two things achieved with this:
                    //  1. Keyguard is hidden when the setup wizard is shown. This part is already
                    //     implemented in scene container by disabling visibility instead of going
                    //     to Gone. See [SceneContainerStartable.hydrateVisibility]. We might want
                    //     to unify this logic here.
                    //  2. When the auth method is set to NONE device boots into Gone (Launcher).
                    //     For this we would just need to call changeScene(Scene.Gone).
                    //     Unfortunately STL doesn't seem to be initialized at this point, therefore
                    //     it needs a different solution.
                    repository.emitInitialStepsFromOff(LOCKSCREEN)
                } else {
                    repository.emitInitialStepsFromOff(
                        if (showLockscreenOnBoot.first()) LOCKSCREEN else GONE
                        if (onBootTransitionInteractor.showLockscreenOnBoot()) LOCKSCREEN else GONE
                    )
                }
            }
+47 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 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.scene.domain.interactor

import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.deviceentry.domain.interactor.DeviceEntryInteractor
import com.android.systemui.scene.shared.model.Scenes
import com.android.systemui.statusbar.policy.domain.interactor.DeviceProvisioningInteractor
import javax.inject.Inject

@SysUISingleton
class OnBootTransitionInteractor
@Inject
constructor(
    val deviceEntryInteractor: DeviceEntryInteractor,
    val deviceProvisioningInteractor: DeviceProvisioningInteractor,
    val sceneInteractor: SceneInteractor,
) {

    /** Whether the lockscreen should be showing when the device starts up for the first time. */
    suspend fun showLockscreenOnBoot(): Boolean {
        return (deviceProvisioningInteractor.isDeviceProvisioned() ||
            deviceEntryInteractor.isAuthenticationRequired()) &&
            deviceEntryInteractor.isLockscreenEnabled()
    }

    /** Instantly snap to [Scenes.Gone] if the lockscreen should not be shown. */
    suspend fun maybeChangeInitialScene() {
        if (!showLockscreenOnBoot()) {
            sceneInteractor.snapToScene(Scenes.Gone, "No authentication on boot")
        }
    }
}
+7 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ import com.android.systemui.keyguard.ui.viewmodel.LightRevealScrimViewModel
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.lifecycle.Hydrator
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.scene.domain.interactor.OnBootTransitionInteractor
import com.android.systemui.scene.domain.interactor.SceneInteractor
import com.android.systemui.scene.shared.logger.SceneLogger
import com.android.systemui.scene.shared.model.Overlays
@@ -64,6 +65,7 @@ constructor(
    private val sceneInteractor: SceneInteractor,
    private val falsingInteractor: FalsingInteractor,
    private val powerInteractor: PowerInteractor,
    private val onBootTransitionInteractor: OnBootTransitionInteractor,
    shadeModeInteractor: ShadeModeInteractor,
    private val remoteInputInteractor: RemoteInputInteractor,
    private val logger: SceneLogger,
@@ -321,6 +323,11 @@ constructor(
        return sceneInteractor.filteredUserActions(unfiltered)
    }

    /** Immediately changes the initial scene if necessary. */
    suspend fun onInitialComposition() {
        onBootTransitionInteractor.maybeChangeInitialScene()
    }

    /**
     * Returns `true` if transitioning to [content] is permissible by the falsing system; `false`
     * otherwise.
+2 −0
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import com.android.systemui.deviceentry.domain.interactor.deviceEntryInteractor
import com.android.systemui.keyguard.data.repository.keyguardTransitionRepository
import com.android.systemui.kosmos.Kosmos
import com.android.systemui.kosmos.applicationCoroutineScope
import com.android.systemui.scene.domain.interactor.onBootTransitionInteractor
import com.android.systemui.statusbar.policy.domain.interactor.deviceProvisioningInteractor

val Kosmos.keyguardTransitionBootInteractor: KeyguardTransitionBootInteractor by
@@ -31,5 +32,6 @@ val Kosmos.keyguardTransitionBootInteractor: KeyguardTransitionBootInteractor by
            keyguardTransitionInteractor = keyguardTransitionInteractor,
            repository = keyguardTransitionRepository,
            internalTransitionInteractor = internalKeyguardTransitionInteractor,
            onBootTransitionInteractor = onBootTransitionInteractor,
        )
    }
Loading