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

Commit 27311fa6 authored by Darrell Shi's avatar Darrell Shi Committed by Android (Google) Code Review
Browse files

Merge "Log ui events for transitions between hub and dream" into main

parents eb6c6a97 a2c7d989
Loading
Loading
Loading
Loading
+159 −11
Original line number Diff line number Diff line
@@ -22,10 +22,13 @@ import com.android.compose.animation.scene.ObservableTransitionState
import com.android.compose.animation.scene.SceneKey
import com.android.internal.logging.UiEventLogger
import com.android.systemui.SysuiTestCase
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.communal.domain.interactor.communalSceneInteractor
import com.android.systemui.communal.shared.log.CommunalUiEvent
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.keyguard.data.repository.FakeKeyguardRepository
import com.android.systemui.keyguard.data.repository.fakeKeyguardRepository
import com.android.systemui.keyguard.domain.interactor.keyguardInteractor
import com.android.systemui.kosmos.testScope
import com.android.systemui.testKosmos
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -53,18 +56,21 @@ class CommunalLoggerStartableTest : SysuiTestCase() {
    private val kosmos = testKosmos()
    private val testScope = kosmos.testScope

    private lateinit var communalInteractor: CommunalInteractor
    private lateinit var communalSceneInteractor: CommunalSceneInteractor
    private lateinit var keyguardRepository: FakeKeyguardRepository
    private lateinit var underTest: CommunalLoggerStartable

    @Before
    fun setUp() {
        MockitoAnnotations.initMocks(this)
        communalInteractor = kosmos.communalInteractor
        communalSceneInteractor = kosmos.communalSceneInteractor
        keyguardRepository = kosmos.fakeKeyguardRepository

        underTest =
            CommunalLoggerStartable(
                testScope.backgroundScope,
                communalInteractor,
                communalSceneInteractor,
                kosmos.keyguardInteractor,
                uiEventLogger,
            )
        underTest.start()
@@ -73,10 +79,13 @@ class CommunalLoggerStartableTest : SysuiTestCase() {
    @Test
    fun transitionStateLogging_enterCommunalHub() =
        testScope.runTest {
            // Not dreaming
            keyguardRepository.setDreamingWithOverlay(false)

            // Transition state is default (non-communal)
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(idle(CommunalScenes.Default))
            communalInteractor.setTransitionState(transitionState)
            communalSceneInteractor.setTransitionState(transitionState)
            runCurrent()

            // Verify nothing is logged from the default state
@@ -99,12 +108,15 @@ class CommunalLoggerStartableTest : SysuiTestCase() {
        }

    @Test
    fun transitionStateLogging_enterCommunalHub_canceled() =
    fun transitionStateLogging_cancelEnteringCommunalHub() =
        testScope.runTest {
            // Not dreaming
            keyguardRepository.setDreamingWithOverlay(false)

            // Transition state is default (non-communal)
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(idle(CommunalScenes.Default))
            communalInteractor.setTransitionState(transitionState)
            communalSceneInteractor.setTransitionState(transitionState)
            runCurrent()

            // Verify nothing is logged from the default state
@@ -132,10 +144,13 @@ class CommunalLoggerStartableTest : SysuiTestCase() {
    @Test
    fun transitionStateLogging_exitCommunalHub() =
        testScope.runTest {
            // Not dreaming
            keyguardRepository.setDreamingWithOverlay(false)

            // Transition state is communal
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(idle(CommunalScenes.Communal))
            communalInteractor.setTransitionState(transitionState)
            communalSceneInteractor.setTransitionState(transitionState)
            runCurrent()

            // Verify SHOWN is logged when it's the default state
@@ -158,12 +173,15 @@ class CommunalLoggerStartableTest : SysuiTestCase() {
        }

    @Test
    fun transitionStateLogging_exitCommunalHub_canceled() =
    fun transitionStateLogging_cancelExitingCommunalHub() =
        testScope.runTest {
            // Not dreaming
            keyguardRepository.setDreamingWithOverlay(false)

            // Transition state is communal
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(idle(CommunalScenes.Communal))
            communalInteractor.setTransitionState(transitionState)
            communalSceneInteractor.setTransitionState(transitionState)
            runCurrent()

            // Clear the initial SHOWN event from the logger
@@ -188,6 +206,136 @@ class CommunalLoggerStartableTest : SysuiTestCase() {
            verify(uiEventLogger, never()).log(CommunalUiEvent.COMMUNAL_HUB_GONE)
        }

    @Test
    fun transitionStateLogging_dreaming_enterCommunalHub() =
        testScope.runTest {
            // Dreaming
            keyguardRepository.setDreamingWithOverlay(true)

            // Transition state is default (non-communal)
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(idle(CommunalScenes.Default))
            communalSceneInteractor.setTransitionState(transitionState)
            runCurrent()

            // Verify nothing is logged from the default state
            verify(uiEventLogger, never()).log(any())

            // Start transition to communal
            transitionState.value = transition(to = CommunalScenes.Communal)
            runCurrent()

            // Verify UiEvent logged
            verify(uiEventLogger).log(CommunalUiEvent.DREAM_TO_COMMUNAL_HUB_SWIPE_START)

            // Finish transition to communal
            transitionState.value = idle(CommunalScenes.Communal)
            runCurrent()

            // Verify UiEvent logged
            verify(uiEventLogger).log(CommunalUiEvent.DREAM_TO_COMMUNAL_HUB_SWIPE_FINISH)
            verify(uiEventLogger).log(CommunalUiEvent.COMMUNAL_HUB_SHOWN)
        }

    @Test
    fun transitionStateLogging_dreaming_cancelEnteringCommunalHub() =
        testScope.runTest {
            // Dreaming
            keyguardRepository.setDreamingWithOverlay(true)

            // Transition state is default (non-communal)
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(idle(CommunalScenes.Default))
            communalSceneInteractor.setTransitionState(transitionState)
            runCurrent()

            // Verify nothing is logged from the default state
            verify(uiEventLogger, never()).log(any())

            // Start transition to communal
            transitionState.value = transition(to = CommunalScenes.Communal)
            runCurrent()

            // Verify UiEvent logged
            verify(uiEventLogger).log(CommunalUiEvent.DREAM_TO_COMMUNAL_HUB_SWIPE_START)

            // Cancel the transition
            transitionState.value = idle(CommunalScenes.Default)
            runCurrent()

            // Verify UiEvent logged
            verify(uiEventLogger).log(CommunalUiEvent.DREAM_TO_COMMUNAL_HUB_SWIPE_CANCEL)

            // Verify neither SHOWN nor GONE is logged
            verify(uiEventLogger, never()).log(CommunalUiEvent.COMMUNAL_HUB_SHOWN)
            verify(uiEventLogger, never()).log(CommunalUiEvent.COMMUNAL_HUB_GONE)
        }

    @Test
    fun transitionStateLogging_dreaming_exitCommunalHub() =
        testScope.runTest {
            // Dreaming
            keyguardRepository.setDreamingWithOverlay(true)

            // Transition state is communal
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(idle(CommunalScenes.Communal))
            communalSceneInteractor.setTransitionState(transitionState)
            runCurrent()

            // Verify SHOWN is logged when it's the default state
            verify(uiEventLogger).log(CommunalUiEvent.COMMUNAL_HUB_SHOWN)

            // Start transition from communal
            transitionState.value = transition(from = CommunalScenes.Communal)
            runCurrent()

            // Verify UiEvent logged
            verify(uiEventLogger).log(CommunalUiEvent.COMMUNAL_HUB_TO_DREAM_SWIPE_START)

            // Finish transition to communal
            transitionState.value = idle(CommunalScenes.Default)
            runCurrent()

            // Verify UiEvent logged
            verify(uiEventLogger).log(CommunalUiEvent.COMMUNAL_HUB_TO_DREAM_SWIPE_FINISH)
            verify(uiEventLogger).log(CommunalUiEvent.COMMUNAL_HUB_GONE)
        }

    @Test
    fun transitionStateLogging_dreaming_cancelExitingCommunalHub() =
        testScope.runTest {
            // Dreaming
            keyguardRepository.setDreamingWithOverlay(true)

            // Transition state is communal
            val transitionState =
                MutableStateFlow<ObservableTransitionState>(idle(CommunalScenes.Communal))
            communalSceneInteractor.setTransitionState(transitionState)
            runCurrent()

            // Clear the initial SHOWN event from the logger
            clearInvocations(uiEventLogger)

            // Start transition from communal
            transitionState.value = transition(from = CommunalScenes.Communal)
            runCurrent()

            // Verify UiEvent logged
            verify(uiEventLogger).log(CommunalUiEvent.COMMUNAL_HUB_TO_DREAM_SWIPE_START)

            // Cancel the transition
            transitionState.value = idle(CommunalScenes.Communal)
            runCurrent()

            // Verify UiEvent logged
            verify(uiEventLogger).log(CommunalUiEvent.COMMUNAL_HUB_TO_DREAM_SWIPE_CANCEL)

            // Verify neither SHOWN nor GONE is logged
            verify(uiEventLogger, never()).log(CommunalUiEvent.COMMUNAL_HUB_SHOWN)
            verify(uiEventLogger, never()).log(CommunalUiEvent.COMMUNAL_HUB_GONE)
        }

    private fun transition(
        from: SceneKey = CommunalScenes.Default,
        to: SceneKey = CommunalScenes.Default,
+2 −0
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import com.android.systemui.communal.data.repository.fakeCommunalSceneRepository
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.communalInteractor
import com.android.systemui.communal.domain.interactor.setCommunalAvailable
import com.android.systemui.communal.shared.log.CommunalUiEvent
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.complication.ComplicationHostViewController
import com.android.systemui.complication.ComplicationLayoutEngine
@@ -660,6 +661,7 @@ class DreamOverlayServiceTest : SysuiTestCase() {
            verify(mDreamOverlayCallback).onRedirectWake(true)
            client.onWakeRequested()
            verify(mCommunalInteractor).changeScene(eq(CommunalScenes.Communal), isNull())
            verify(mUiEventLogger).log(CommunalUiEvent.DREAM_TO_COMMUNAL_HUB_DREAM_AWAKE_START)
        }

    @Test
+38 −11
Original line number Diff line number Diff line
@@ -19,14 +19,16 @@ package com.android.systemui.communal.log
import com.android.compose.animation.scene.ObservableTransitionState
import com.android.internal.logging.UiEventLogger
import com.android.systemui.CoreStartable
import com.android.systemui.communal.domain.interactor.CommunalInteractor
import com.android.systemui.communal.domain.interactor.CommunalSceneInteractor
import com.android.systemui.communal.shared.log.CommunalUiEvent
import com.android.systemui.communal.shared.model.CommunalScenes
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.keyguard.domain.interactor.KeyguardInteractor
import com.android.systemui.util.kotlin.pairwise
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.drop
import kotlinx.coroutines.flow.filterNotNull
@@ -40,12 +42,13 @@ class CommunalLoggerStartable
@Inject
constructor(
    @Background private val backgroundScope: CoroutineScope,
    private val communalInteractor: CommunalInteractor,
    private val communalSceneInteractor: CommunalSceneInteractor,
    private val keyguardInteractor: KeyguardInteractor,
    private val uiEventLogger: UiEventLogger,
) : CoreStartable {

    override fun start() {
        communalInteractor.transitionState
        communalSceneInteractor.transitionState
            .map { state ->
                when {
                    state.isOnCommunal() -> CommunalUiEvent.COMMUNAL_HUB_SHOWN
@@ -60,22 +63,46 @@ constructor(
            .onEach { uiEvent -> uiEventLogger.log(uiEvent) }
            .launchIn(backgroundScope)

        communalInteractor.transitionState
        communalSceneInteractor.transitionState
            .pairwise()
            .map { (old, new) ->
            .combine(keyguardInteractor.isDreamingWithOverlay) { (old, new), isDreaming ->
                when {
                    new.isOnCommunal() && old.isSwipingToCommunal() ->
                        if (isDreaming) {
                            CommunalUiEvent.DREAM_TO_COMMUNAL_HUB_SWIPE_FINISH
                        } else {
                            CommunalUiEvent.COMMUNAL_HUB_SWIPE_TO_ENTER_FINISH
                        }
                    new.isOnCommunal() && old.isSwipingFromCommunal() ->
                        if (isDreaming) {
                            CommunalUiEvent.COMMUNAL_HUB_TO_DREAM_SWIPE_CANCEL
                        } else {
                            CommunalUiEvent.COMMUNAL_HUB_SWIPE_TO_EXIT_CANCEL
                        }
                    new.isNotOnCommunal() && old.isSwipingFromCommunal() ->
                        if (isDreaming) {
                            CommunalUiEvent.COMMUNAL_HUB_TO_DREAM_SWIPE_FINISH
                        } else {
                            CommunalUiEvent.COMMUNAL_HUB_SWIPE_TO_EXIT_FINISH
                        }
                    new.isNotOnCommunal() && old.isSwipingToCommunal() ->
                        if (isDreaming) {
                            CommunalUiEvent.DREAM_TO_COMMUNAL_HUB_SWIPE_CANCEL
                        } else {
                            CommunalUiEvent.COMMUNAL_HUB_SWIPE_TO_ENTER_CANCEL
                        }
                    new.isSwipingToCommunal() && old.isNotOnCommunal() ->
                        if (isDreaming) {
                            CommunalUiEvent.DREAM_TO_COMMUNAL_HUB_SWIPE_START
                        } else {
                            CommunalUiEvent.COMMUNAL_HUB_SWIPE_TO_ENTER_START
                        }
                    new.isSwipingFromCommunal() && old.isOnCommunal() ->
                        if (isDreaming) {
                            CommunalUiEvent.COMMUNAL_HUB_TO_DREAM_SWIPE_START
                        } else {
                            CommunalUiEvent.COMMUNAL_HUB_SWIPE_TO_EXIT_START
                        }
                    else -> null
                }
            }
+14 −8
Original line number Diff line number Diff line
@@ -54,14 +54,20 @@ enum class CommunalUiEvent(private val id: Int) : UiEventEnum {
    COMMUNAL_HUB_SWIPE_UP_TO_BOUNCER(1573),
    @UiEvent(doc = "User performs a swipe down gesture from top to enter shade")
    COMMUNAL_HUB_SWIPE_DOWN_TO_SHADE(1574),
    @UiEvent(doc = "User performs a tap gesture on the UMO in Communal Hub")
    COMMUNAL_HUB_UMO_TAP(1858),
    @UiEvent(
        doc =
            "A transition from dream to Communal Hub starts. This can be triggered by a tap on " +
                "the dream."
    )
    FROM_DREAM_TO_COMMUNAL_HUB_TRANSITION_START(1859);
    @UiEvent(doc = "User starts the swipe gesture to enter the Communal Hub from Dream")
    DREAM_TO_COMMUNAL_HUB_SWIPE_START(1860),
    @UiEvent(doc = "User finishes the swipe gesture to enter the Communal Hub from Dream")
    DREAM_TO_COMMUNAL_HUB_SWIPE_FINISH(1861),
    @UiEvent(doc = "User cancels the swipe gesture to enter the Communal Hub from Dream")
    DREAM_TO_COMMUNAL_HUB_SWIPE_CANCEL(1862),
    @UiEvent(doc = "User starts the swipe gesture to exit the Communal Hub to go to Dream")
    COMMUNAL_HUB_TO_DREAM_SWIPE_START(1863),
    @UiEvent(doc = "User finishes the swipe gesture to exit the Communal Hub to go to Dream")
    COMMUNAL_HUB_TO_DREAM_SWIPE_FINISH(1864),
    @UiEvent(doc = "User cancels the swipe gesture to exit the Communal Hub to go to Dream")
    COMMUNAL_HUB_TO_DREAM_SWIPE_CANCEL(1865),
    @UiEvent(doc = "A transition from Dream to Communal Hub starts due to dream awakening")
    DREAM_TO_COMMUNAL_HUB_DREAM_AWAKE_START(1866);

    override fun getId(): Int {
        return id
+2 −0
Original line number Diff line number Diff line
@@ -56,6 +56,7 @@ import com.android.systemui.ambient.touch.TouchMonitor;
import com.android.systemui.ambient.touch.dagger.AmbientTouchComponent;
import com.android.systemui.ambient.touch.scrim.ScrimManager;
import com.android.systemui.communal.domain.interactor.CommunalInteractor;
import com.android.systemui.communal.shared.log.CommunalUiEvent;
import com.android.systemui.communal.shared.model.CommunalScenes;
import com.android.systemui.complication.Complication;
import com.android.systemui.complication.dagger.ComplicationComponent;
@@ -407,6 +408,7 @@ public class DreamOverlayService extends android.service.dreams.DreamOverlayServ

    @Override
    public void onWakeRequested() {
        mUiEventLogger.log(CommunalUiEvent.DREAM_TO_COMMUNAL_HUB_DREAM_AWAKE_START);
        mCommunalInteractor.changeScene(CommunalScenes.Communal, null);
    }