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

Commit 73004139 authored by Chandru S's avatar Chandru S
Browse files

Keep few bouncer coroutines long running to allow dismissing lockscreen when...

Keep few bouncer coroutines long running to allow dismissing lockscreen when bouncer is not currently showing

Bug: 310005730
Test: Remain on the lockscreen after unlocking it with face without bypass
 Tap on a notification that will require bouncer to be shown.
 Lockscreen should get dismissed and the notification app should launch
Flag: com.android.systemui.compose_bouncer
Change-Id: I5a3662033f75cca4b4dfd8834dfc05c121517d62
parent 7bdf2dcf
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -4,17 +4,21 @@ import android.view.ViewGroup
import com.android.keyguard.KeyguardMessageAreaController
import com.android.keyguard.dagger.KeyguardBouncerComponent
import com.android.systemui.bouncer.domain.interactor.BouncerMessageInteractor
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.bouncer.shared.flag.ComposeBouncerFlags
import com.android.systemui.bouncer.ui.BouncerDialogFactory
import com.android.systemui.bouncer.ui.viewmodel.BouncerContainerViewModel
import com.android.systemui.bouncer.ui.viewmodel.BouncerSceneContentViewModel
import com.android.systemui.bouncer.ui.viewmodel.KeyguardBouncerViewModel
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel
import com.android.systemui.log.BouncerLogger
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import dagger.Lazy
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi

/** Helper data class that allows to lazy load all the dependencies of the legacy bouncer. */
@@ -37,6 +41,10 @@ constructor(
data class ComposeBouncerDependencies
@Inject
constructor(
    @Application val applicationScope: CoroutineScope,
    val keyguardInteractor: KeyguardInteractor,
    val selectedUserInteractor: SelectedUserInteractor,
    val legacyInteractor: PrimaryBouncerInteractor,
    val viewModelFactory: BouncerSceneContentViewModel.Factory,
    val dialogFactory: BouncerDialogFactory,
    val bouncerContainerViewModelFactory: BouncerContainerViewModel.Factory,
@@ -58,6 +66,10 @@ constructor(
            val deps = composeBouncerDependencies.get()
            ComposeBouncerViewBinder.bind(
                view,
                deps.applicationScope,
                deps.legacyInteractor,
                deps.keyguardInteractor,
                deps.selectedUserInteractor,
                deps.viewModelFactory,
                deps.dialogFactory,
                deps.bouncerContainerViewModelFactory,
+36 −0
Original line number Diff line number Diff line
@@ -6,23 +6,59 @@ import androidx.activity.OnBackPressedDispatcherOwner
import androidx.activity.setViewTreeOnBackPressedDispatcherOwner
import androidx.compose.ui.platform.ComposeView
import androidx.lifecycle.Lifecycle
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.bouncer.ui.BouncerDialogFactory
import com.android.systemui.bouncer.ui.composable.BouncerContainer
import com.android.systemui.bouncer.ui.viewmodel.BouncerContainerViewModel
import com.android.systemui.bouncer.ui.viewmodel.BouncerSceneContentViewModel
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.lifecycle.WindowLifecycleState
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.lifecycle.viewModel
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import com.android.systemui.util.kotlin.sample
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Job
import kotlinx.coroutines.awaitCancellation
import kotlinx.coroutines.launch

/** View binder responsible for binding the compose version of the bouncer. */
object ComposeBouncerViewBinder {
    private var persistentBouncerJob: Job? = null

    fun bind(
        view: ViewGroup,
        scope: CoroutineScope,
        legacyInteractor: PrimaryBouncerInteractor,
        keyguardInteractor: KeyguardInteractor,
        selectedUserInteractor: SelectedUserInteractor,
        viewModelFactory: BouncerSceneContentViewModel.Factory,
        dialogFactory: BouncerDialogFactory,
        bouncerContainerViewModelFactory: BouncerContainerViewModel.Factory,
    ) {
        persistentBouncerJob?.cancel()
        persistentBouncerJob =
            scope.launch {
                launch {
                    legacyInteractor.isShowing
                        .sample(keyguardInteractor.isKeyguardDismissible, ::Pair)
                        .collect { (isShowing, dismissible) ->
                            if (isShowing && dismissible) {
                                legacyInteractor.notifyUserRequestedBouncerWhenAlreadyAuthenticated(
                                    selectedUserInteractor.getSelectedUserId()
                                )
                            }
                        }
                }

                launch {
                    legacyInteractor.startingDisappearAnimation.collect {
                        it.run()
                        legacyInteractor.hide()
                    }
                }
            }

        view.repeatWhenAttached {
            view.viewModel(
                minWindowLifecycleState = WindowLifecycleState.ATTACHED,
+0 −22
Original line number Diff line number Diff line
@@ -18,10 +18,8 @@ package com.android.systemui.bouncer.ui.viewmodel

import com.android.systemui.authentication.domain.interactor.AuthenticationInteractor
import com.android.systemui.bouncer.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.deviceentry.domain.interactor.DeviceUnlockedInteractor
import com.android.systemui.lifecycle.ExclusiveActivatable
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import com.android.systemui.util.kotlin.sample
import dagger.assisted.AssistedFactory
import dagger.assisted.AssistedInject
import kotlinx.coroutines.awaitCancellation
@@ -34,23 +32,10 @@ constructor(
    private val legacyInteractor: PrimaryBouncerInteractor,
    private val authenticationInteractor: AuthenticationInteractor,
    private val selectedUserInteractor: SelectedUserInteractor,
    private val deviceUnlockedInteractor: DeviceUnlockedInteractor,
) : ExclusiveActivatable() {

    override suspend fun onActivated(): Nothing {
        coroutineScope {
            launch {
                legacyInteractor.isShowing
                    .sample(deviceUnlockedInteractor.deviceUnlockStatus, ::Pair)
                    .collect { (isShowing, unlockStatus) ->
                        if (isShowing && unlockStatus.isUnlocked) {
                            legacyInteractor.notifyUserRequestedBouncerWhenAlreadyAuthenticated(
                                selectedUserInteractor.getSelectedUserId()
                            )
                        }
                    }
            }

            launch {
                authenticationInteractor.onAuthenticationResult.collect { authenticationSucceeded ->
                    if (authenticationSucceeded) {
@@ -60,13 +45,6 @@ constructor(
                    }
                }
            }

            launch {
                legacyInteractor.startingDisappearAnimation.collect {
                    it.run()
                    legacyInteractor.hide()
                }
            }
            awaitCancellation()
        }
    }