Merge "Keep few bouncer coroutines long running to allow dismissing lockscreen when bouncer is not currently showing" into main
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
index 49dadce..12f06bb 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/BouncerViewBinder.kt
@@ -4,17 +4,21 @@
 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 @@
 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 @@
             val deps = composeBouncerDependencies.get()
             ComposeBouncerViewBinder.bind(
                 view,
+                deps.applicationScope,
+                deps.legacyInteractor,
+                deps.keyguardInteractor,
+                deps.selectedUserInteractor,
                 deps.viewModelFactory,
                 deps.dialogFactory,
                 deps.bouncerContainerViewModelFactory,
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/ComposeBouncerViewBinder.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/ComposeBouncerViewBinder.kt
index fdbc18d..80c4291 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/ComposeBouncerViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/binder/ComposeBouncerViewBinder.kt
@@ -6,23 +6,59 @@
 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,
diff --git a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerContainerViewModel.kt b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerContainerViewModel.kt
index 5a4f8eb..615cb5b 100644
--- a/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerContainerViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/bouncer/ui/viewmodel/BouncerContainerViewModel.kt
@@ -18,10 +18,8 @@
 
 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,24 +32,11 @@
     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) {
                         legacyInteractor.notifyKeyguardAuthenticatedPrimaryAuth(
@@ -60,13 +45,6 @@
                     }
                 }
             }
-
-            launch {
-                legacyInteractor.startingDisappearAnimation.collect {
-                    it.run()
-                    legacyInteractor.hide()
-                }
-            }
             awaitCancellation()
         }
     }