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

Commit 977a6d61 authored by William Xiao's avatar William Xiao
Browse files

Add transitions between glanceable hub and bouncer

Also updates touch handling so that bottom edge swipes on the hub can
open the bouncer.

The animations between the hub and bouncer(s) already work fine, this
change just adds proper keyguard transitions so that the transition
state is correct.

Bug: 315207481
Bug: 315194778
Test: atest KeyguardTransitionScenariosTest GlanceableHubContainerControllerTest
Test: manually verified through logs that keyguard transition state is
      accurate when going between hub and bouncer
Flag: ACONFIG com.android.systemui.communal_hub DEVELOPMENT
Change-Id: I79a0f01f3379f22032edaa4bcc89d5193c3d2a46
parent abf9f57a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -1732,6 +1732,8 @@
    <dimen name="communal_right_edge_swipe_region_width">16dp</dimen>
    <!-- Height of area at top of communal hub where swipes should open the notification shade -->
    <dimen name="communal_top_edge_swipe_region_height">32dp</dimen>
    <!-- Height of area at bottom of communal hub where swipes should open the bouncer -->
    <dimen name="communal_bottom_edge_swipe_region_height">32dp</dimen>

    <dimen name="drag_and_drop_icon_size">70dp</dimen>

+17 −15
Original line number Diff line number Diff line
@@ -17,14 +17,14 @@
package com.android.systemui.keyguard.domain.interactor

import android.animation.ValueAnimator
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
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.Utils.Companion.toQuint
import com.android.systemui.util.kotlin.Utils.Companion.sample
import com.android.systemui.util.kotlin.sample
import com.android.wm.shell.animation.Interpolators
import javax.inject.Inject
@@ -32,7 +32,6 @@ import kotlin.time.Duration.Companion.milliseconds
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.launch

@@ -46,6 +45,7 @@ constructor(
    @Background bgDispatcher: CoroutineDispatcher,
    @Main mainDispatcher: CoroutineDispatcher,
    private val keyguardInteractor: KeyguardInteractor,
    private val communalInteractor: CommunalInteractor,
    private val powerInteractor: PowerInteractor,
) :
    TransitionInteractor(
@@ -57,12 +57,12 @@ constructor(

    override fun start() {
        listenForAlternateBouncerToGone()
        listenForAlternateBouncerToLockscreenAodOrDozing()
        listenForAlternateBouncerToLockscreenHubAodOrDozing()
        listenForAlternateBouncerToPrimaryBouncer()
        listenForTransitionToCamera(scope, keyguardInteractor)
    }

    private fun listenForAlternateBouncerToLockscreenAodOrDozing() {
    private fun listenForAlternateBouncerToLockscreenHubAodOrDozing() {
        scope.launch {
            keyguardInteractor.alternateBouncerShowing
                // Add a slight delay, as alternateBouncer and primaryBouncer showing event changes
@@ -70,14 +70,11 @@ constructor(
                // happening prematurely.
                .onEach { delay(50) }
                .sample(
                    combine(
                    keyguardInteractor.primaryBouncerShowing,
                    startedKeyguardTransitionStep,
                    powerInteractor.isAwake,
                    keyguardInteractor.isAodAvailable,
                        ::toQuad
                    ),
                    ::toQuint
                    communalInteractor.isIdleOnCommunal
                )
                .collect {
                    (
@@ -85,7 +82,8 @@ constructor(
                        isPrimaryBouncerShowing,
                        lastStartedTransitionStep,
                        isAwake,
                        isAodAvailable) ->
                        isAodAvailable,
                        isIdleOnCommunal) ->
                    if (
                        !isAlternateBouncerShowing &&
                            !isPrimaryBouncerShowing &&
@@ -98,9 +96,13 @@ constructor(
                                } else {
                                    KeyguardState.DOZING
                                }
                            } else {
                                if (isIdleOnCommunal) {
                                    KeyguardState.GLANCEABLE_HUB
                                } else {
                                    KeyguardState.LOCKSCREEN
                                }
                            }
                        startTransitionTo(to)
                    }
                }
+37 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.keyguard.domain.interactor

import android.animation.ValueAnimator
import com.android.app.animation.Interpolators
import com.android.app.tracing.coroutines.launch
import com.android.systemui.Flags
import com.android.systemui.communal.shared.model.CommunalSceneKey
import com.android.systemui.dagger.SysUISingleton
@@ -40,6 +41,7 @@ class FromGlanceableHubTransitionInteractor
constructor(
    @Background private val scope: CoroutineScope,
    private val glanceableHubTransitions: GlanceableHubTransitions,
    private val keyguardInteractor: KeyguardInteractor,
    override val transitionRepository: KeyguardTransitionRepository,
    transitionInteractor: KeyguardTransitionInteractor,
    private val powerInteractor: PowerInteractor,
@@ -58,6 +60,8 @@ constructor(
        }
        listenForHubToLockscreen()
        listenForHubToDozing()
        listenForHubToPrimaryBouncer()
        listenForHubToAlternateBouncer()
    }

    override fun getDefaultAnimatorForTransitionsToState(toState: KeyguardState): ValueAnimator {
@@ -75,10 +79,42 @@ constructor(
        glanceableHubTransitions.listenForLockscreenAndHubTransition(
            transitionName = "listenForHubToLockscreen",
            transitionOwnerName = TAG,
            toScene = CommunalSceneKey.Blank
            toScene = CommunalSceneKey.Blank,
        )
    }

    private fun listenForHubToPrimaryBouncer() {
        scope.launch("$TAG#listenForHubToPrimaryBouncer") {
            keyguardInteractor.primaryBouncerShowing
                .sample(startedKeyguardTransitionStep, ::Pair)
                .collect { pair ->
                    val (isBouncerShowing, lastStartedTransitionStep) = pair
                    if (
                        isBouncerShowing &&
                            lastStartedTransitionStep.to == KeyguardState.GLANCEABLE_HUB
                    ) {
                        startTransitionTo(KeyguardState.PRIMARY_BOUNCER)
                    }
                }
        }
    }

    private fun listenForHubToAlternateBouncer() {
        scope.launch("$TAG#listenForHubToAlternateBouncer") {
            keyguardInteractor.alternateBouncerShowing
                .sample(startedKeyguardTransitionStep, ::Pair)
                .collect { pair ->
                    val (isAlternateBouncerShowing, lastStartedTransitionStep) = pair
                    if (
                        isAlternateBouncerShowing &&
                            lastStartedTransitionStep.to == KeyguardState.GLANCEABLE_HUB
                    ) {
                        startTransitionTo(KeyguardState.ALTERNATE_BOUNCER)
                    }
                }
        }
    }

    private fun listenForHubToDozing() {
        scope.launch {
            powerInteractor.isAsleep.sample(startedKeyguardTransitionStep, ::Pair).collect {
+21 −15
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.systemui.keyguard.domain.interactor

import android.animation.ValueAnimator
import com.android.keyguard.KeyguardSecurityModel
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.dagger.qualifiers.Main
@@ -29,8 +30,8 @@ import com.android.systemui.keyguard.shared.model.KeyguardSurfaceBehindModel
import com.android.systemui.keyguard.shared.model.TransitionModeOnCanceled
import com.android.systemui.power.domain.interactor.PowerInteractor
import com.android.systemui.user.domain.interactor.SelectedUserInteractor
import com.android.systemui.util.kotlin.Utils.Companion.sample
import com.android.systemui.util.kotlin.Utils.Companion.toQuad
import com.android.systemui.util.kotlin.Utils.Companion.toQuint
import com.android.systemui.util.kotlin.Utils.Companion.toTriple
import com.android.systemui.util.kotlin.sample
import com.android.wm.shell.animation.Interpolators
@@ -54,6 +55,7 @@ constructor(
    @Background bgDispatcher: CoroutineDispatcher,
    @Main mainDispatcher: CoroutineDispatcher,
    private val keyguardInteractor: KeyguardInteractor,
    private val communalInteractor: CommunalInteractor,
    private val flags: FeatureFlags,
    private val keyguardSecurityModel: KeyguardSecurityModel,
    private val selectedUserInteractor: SelectedUserInteractor,
@@ -69,7 +71,7 @@ constructor(
    override fun start() {
        listenForPrimaryBouncerToGone()
        listenForPrimaryBouncerToAodOrDozing()
        listenForPrimaryBouncerToLockscreenOrOccluded()
        listenForPrimaryBouncerToLockscreenHubOrOccluded()
        listenForPrimaryBouncerToDreamingLockscreenHosted()
        listenForTransitionToCamera(scope, keyguardInteractor)
    }
@@ -125,18 +127,15 @@ constructor(
        scope.launch { startTransitionTo(KeyguardState.GONE) }
    }

    private fun listenForPrimaryBouncerToLockscreenOrOccluded() {
    private fun listenForPrimaryBouncerToLockscreenHubOrOccluded() {
        scope.launch {
            keyguardInteractor.primaryBouncerShowing
                .sample(
                    combine(
                    powerInteractor.isAwake,
                    startedKeyguardTransitionStep,
                    keyguardInteractor.isKeyguardOccluded,
                    keyguardInteractor.isActiveDreamLockscreenHosted,
                        ::toQuad
                    ),
                    ::toQuint
                    communalInteractor.isIdleOnCommunal
                )
                .collect {
                    (
@@ -144,16 +143,23 @@ constructor(
                        isAwake,
                        lastStartedTransitionStep,
                        occluded,
                        isActiveDreamLockscreenHosted) ->
                        isActiveDreamLockscreenHosted,
                        isIdleOnCommunal) ->
                    if (
                        !isBouncerShowing &&
                            lastStartedTransitionStep.to == KeyguardState.PRIMARY_BOUNCER &&
                            isAwake &&
                            !isActiveDreamLockscreenHosted
                    ) {
                        startTransitionTo(
                            if (occluded) KeyguardState.OCCLUDED else KeyguardState.LOCKSCREEN
                        )
                        val toState =
                            if (occluded) {
                                KeyguardState.OCCLUDED
                            } else if (isIdleOnCommunal) {
                                KeyguardState.GLANCEABLE_HUB
                            } else {
                                KeyguardState.LOCKSCREEN
                            }
                        startTransitionTo(toState)
                    }
                }
        }
+8 −1
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalTransitionProgress
import com.android.systemui.communal.shared.model.CommunalSceneKey
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyguard.data.repository.KeyguardTransitionRepository
import com.android.systemui.keyguard.shared.model.KeyguardState
import com.android.systemui.keyguard.shared.model.TransitionInfo
@@ -30,12 +31,15 @@ import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.util.kotlin.sample
import java.util.UUID
import javax.inject.Inject
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.flowOn

class GlanceableHubTransitions
@Inject
constructor(
    @Application private val scope: CoroutineScope,
    @Background private val bgDispatcher: CoroutineDispatcher,
    private val transitionInteractor: KeyguardTransitionInteractor,
    private val transitionRepository: KeyguardTransitionRepository,
    private val communalInteractor: CommunalInteractor,
@@ -66,7 +70,10 @@ constructor(
        scope.launch("$transitionOwnerName#$transitionName") {
            communalInteractor
                .transitionProgressToScene(toScene)
                .sample(transitionInteractor.startedKeyguardTransitionStep, ::Pair)
                .sample(
                    transitionInteractor.startedKeyguardTransitionStep.flowOn(bgDispatcher),
                    ::Pair
                )
                .collect { pair ->
                    val (transitionProgress, lastStartedStep) = pair

Loading