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

Commit 81cbca86 authored by Ale Nijamkin's avatar Ale Nijamkin
Browse files

[flexiglass] Hint and tooltip happen at the same time

Bug: 406213664
Test: unit tests updated
Test: manually verified bounce and tooltip behaviour on both sides
Flag: com.android.systemui.scene_container
Change-Id: I46bee43a8c166142c775a158a6fdae642d3667cb
parent 961a2b11
Loading
Loading
Loading
Loading
+14 −68
Original line number Diff line number Diff line
@@ -66,21 +66,13 @@ class DualShadeEducationInteractorTest(private val forOverlay: OverlayKey) : Sys
            // No education before the delay.
            assertEducation(DualShadeEducationModel.None)

            // SHOW THE HINT
            advanceTimeBy(DualShadeEducationInteractor.HINT_APPEARANCE_DELAY_MS - 1)
            // SHOW EDUCATION
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS - 1)
            // No education because didn't wait quite long enough yet.
            assertEducation(DualShadeEducationModel.None)
            advanceTimeBy(1)
            // Expected hint after the full delay.
            assertEducation(expectedHint(forOverlay))

            // SHOW THE TOOLTIP
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS - 1)
            // Still showing the hint because didn't wait quite long enough yet.
            assertEducation(expectedHint(forOverlay))
            advanceTimeBy(1)
            // Expected tooltip after the full delay.
            assertEducation(expectedTooltip(forOverlay))
            // Expected education after the full delay.
            assertEducation(expectedEducation(forOverlay))

            // UI reports impression and dismissal of the tooltip.
            when (forOverlay) {
@@ -100,58 +92,27 @@ class DualShadeEducationInteractorTest(private val forOverlay: OverlayKey) : Sys
            hideOverlay(otherOverlay)
            assertEducation(DualShadeEducationModel.None)
            showOverlay(otherOverlay)
            advanceTimeBy(DualShadeEducationInteractor.HINT_APPEARANCE_DELAY_MS)
            // No hint as it was already shown to the user.
            assertEducation(DualShadeEducationModel.None)
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS)
            // No hint or tooltip as it was already shown to the user.
            // No education as it was already shown to the user.
            assertEducation(DualShadeEducationModel.None)
        }

    @Test
    fun otherOverlayHiddenBeforeHint_noEducation() =
    fun otherOverlayHiddenBeforeEducation_noEducation() =
        kosmos.runTest {
            val otherOverlay = otherOverlay(forOverlay)
            showOverlay(otherOverlay)
            // No tooltip before the delay.
            assertEducation(DualShadeEducationModel.None)

            advanceTimeBy(DualShadeEducationInteractor.HINT_APPEARANCE_DELAY_MS - 1)
            // No hint because didn't wait quite long enough yet.
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS - 1)
            // No education because didn't wait quite long enough yet.
            assertEducation(DualShadeEducationModel.None)

            // Overlay hidden before the delay elapses.
            hideOverlay(otherOverlay)
            assertEducation(DualShadeEducationModel.None)

            advanceTimeBy(1)
            // Waited the entire delay, but the overlay was already hidden.
            assertEducation(DualShadeEducationModel.None)
            // Even waiting for the tooltip doesn't show anything.
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS)
            assertEducation(DualShadeEducationModel.None)
        }

    @Test
    fun otherOverlayHiddenBeforeTooltipDelay_noEducation() =
        kosmos.runTest {
            val otherOverlay = otherOverlay(forOverlay)
            showOverlay(otherOverlay)
            // No tooltip before the delay.
            assertEducation(DualShadeEducationModel.None)

            advanceTimeBy(DualShadeEducationInteractor.HINT_APPEARANCE_DELAY_MS)
            // Showing hint.
            assertEducation(expectedHint(forOverlay))

            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS - 1)
            // Still showing hint as the tooltip delay isn't over.
            assertEducation(expectedHint(forOverlay))

            // Overlay hidden before the tooltip delay elapses.
            hideOverlay(otherOverlay)
            assertEducation(DualShadeEducationModel.None)

            advanceTimeBy(1)
            // Waited the entire delay, but the overlay was already hidden.
            assertEducation(DualShadeEducationModel.None)
@@ -162,8 +123,6 @@ class DualShadeEducationInteractorTest(private val forOverlay: OverlayKey) : Sys
        kosmos.runTest {
            disableDualShade()
            showOverlay(otherOverlay(forOverlay))
            advanceTimeBy(DualShadeEducationInteractor.HINT_APPEARANCE_DELAY_MS)
            assertEducation(DualShadeEducationModel.None)
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS)
            assertEducation(DualShadeEducationModel.None)
        }
@@ -173,10 +132,8 @@ class DualShadeEducationInteractorTest(private val forOverlay: OverlayKey) : Sys
        kosmos.runTest {
            val otherOverlay = otherOverlay(forOverlay)
            showOverlay(otherOverlay)
            advanceTimeBy(DualShadeEducationInteractor.HINT_APPEARANCE_DELAY_MS)
            assertEducation(expectedHint(forOverlay))
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS)
            assertEducation(expectedTooltip(forOverlay))
            assertEducation(expectedEducation(forOverlay))
            when (forOverlay) {
                Overlays.NotificationsShade -> {
                    underTest.recordNotificationsShadeTooltipImpression()
@@ -193,12 +150,9 @@ class DualShadeEducationInteractorTest(private val forOverlay: OverlayKey) : Sys
            selectUser(USER_INFOS[1])

            showOverlay(otherOverlay)
            advanceTimeBy(DualShadeEducationInteractor.HINT_APPEARANCE_DELAY_MS)
            // New user, hint shown again.
            assertEducation(expectedHint(forOverlay))
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS)
            // New user, tooltip shown again.
            assertEducation(expectedTooltip(forOverlay))
            // New user, education shown again.
            assertEducation(expectedEducation(forOverlay))
        }

    /**
@@ -218,18 +172,10 @@ class DualShadeEducationInteractorTest(private val forOverlay: OverlayKey) : Sys
        assertThat(underTest.education).isEqualTo(expected)
    }

    private fun expectedHint(forOverlay: OverlayKey): DualShadeEducationModel {
        return when (forOverlay) {
            Overlays.NotificationsShade -> DualShadeEducationModel.HintForNotificationsShade
            Overlays.QuickSettingsShade -> DualShadeEducationModel.HintForQuickSettingsShade
            else -> DualShadeEducationModel.None
        }
    }

    private fun expectedTooltip(forOverlay: OverlayKey): DualShadeEducationModel {
    private fun expectedEducation(forOverlay: OverlayKey): DualShadeEducationModel {
        return when (forOverlay) {
            Overlays.NotificationsShade -> DualShadeEducationModel.TooltipForNotificationsShade
            Overlays.QuickSettingsShade -> DualShadeEducationModel.TooltipForQuickSettingsShade
            Overlays.NotificationsShade -> DualShadeEducationModel.ForNotificationsShade
            Overlays.QuickSettingsShade -> DualShadeEducationModel.ForQuickSettingsShade
            else -> DualShadeEducationModel.None
        }
    }
+6 −6
Original line number Diff line number Diff line
@@ -82,7 +82,7 @@ class DualShadeEducationalTooltipsViewModelTest(
            showOverlay(otherOverlay)
            // No tooltip before the delay.
            assertNoTooltip()
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS * 2 - 1)
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS - 1)
            // No tooltip because didn't wait quite long enough yet.
            assertNoTooltip()
            advanceTimeBy(1)
@@ -99,7 +99,7 @@ class DualShadeEducationalTooltipsViewModelTest(
            hideOverlay(otherOverlay)
            assertNoTooltip()
            showOverlay(otherOverlay)
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS * 2)
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS)
            // The tooltip should still be gone as it was already shown to the user.
            assertNoTooltip()
        }
@@ -112,7 +112,7 @@ class DualShadeEducationalTooltipsViewModelTest(
            // No tooltip before the delay.
            assertNoTooltip()

            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS * 2 - 1)
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS - 1)
            // No tooltip because didn't wait quite long enough yet.
            assertNoTooltip()

@@ -130,7 +130,7 @@ class DualShadeEducationalTooltipsViewModelTest(
        kosmos.runTest {
            disableDualShade()
            showOverlay(otherOverlay(forOverlay))
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS * 2)
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS)
            assertNoTooltip()
        }

@@ -139,7 +139,7 @@ class DualShadeEducationalTooltipsViewModelTest(
        kosmos.runTest {
            val otherOverlay = otherOverlay(forOverlay)
            showOverlay(otherOverlay)
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS * 2)
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS)
            val tooltip = assertVisibleTooltip(tooltipText)
            tooltip.onShown()
            tooltip.onDismissed()
@@ -149,7 +149,7 @@ class DualShadeEducationalTooltipsViewModelTest(
            selectUser(USER_INFOS[1])

            showOverlay(otherOverlay)
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS * 2)
            advanceTimeBy(DualShadeEducationInteractor.TOOLTIP_APPEARANCE_DELAY_MS)
            // New user, tooltip shown again.
            assertVisibleTooltip(tooltipText)
        }
+9 −29
Original line number Diff line number Diff line
@@ -98,7 +98,7 @@ constructor(
    fun dismissNotificationsShadeTooltip() {
        logD(TAG) { "marking notification shade tooltip as dismissed" }
        backgroundScope.launch {
            if (education == DualShadeEducationModel.TooltipForNotificationsShade) {
            if (education == DualShadeEducationModel.ForNotificationsShade) {
                education = DualShadeEducationModel.None
            }
        }
@@ -107,7 +107,7 @@ constructor(
    fun dismissQuickSettingsShadeTooltip() {
        logD(TAG) { "marking quick settings shade tooltip as dismissed" }
        backgroundScope.launch {
            if (education == DualShadeEducationModel.TooltipForQuickSettingsShade) {
            if (education == DualShadeEducationModel.ForQuickSettingsShade) {
                education = DualShadeEducationModel.None
            }
        }
@@ -145,7 +145,7 @@ constructor(
                    repeatWhenTooltipStillNeedsToBeShown(forOverlay = Overlays.NotificationsShade) {
                        repeatWhenOverlayShown(Overlays.QuickSettingsShade) {
                            repository.setEverShownQuickSettingsShade(true)
                            showEducationAndTooltip(
                            showTooltip(
                                shownOverlay = Overlays.QuickSettingsShade,
                                overlayToEducateAbout = Overlays.NotificationsShade,
                            )
@@ -157,7 +157,7 @@ constructor(
                    repeatWhenTooltipStillNeedsToBeShown(forOverlay = Overlays.QuickSettingsShade) {
                        repeatWhenOverlayShown(Overlays.NotificationsShade) {
                            repository.setEverShownNotificationsShade(true)
                            showEducationAndTooltip(
                            showTooltip(
                                shownOverlay = Overlays.NotificationsShade,
                                overlayToEducateAbout = Overlays.QuickSettingsShade,
                            )
@@ -258,40 +258,21 @@ constructor(
            }
    }

    private suspend fun showEducationAndTooltip(
        shownOverlay: OverlayKey,
        overlayToEducateAbout: OverlayKey,
    ) {
    private suspend fun showTooltip(shownOverlay: OverlayKey, overlayToEducateAbout: OverlayKey) {
        try {
            logD(TAG) {
                "${shownOverlay.debugName} shown, waiting ${HINT_APPEARANCE_DELAY_MS}ms before starting to educate about ${overlayToEducateAbout.debugName}"
            }

            delay(HINT_APPEARANCE_DELAY_MS)
            logD(TAG) {
                "Done waiting ${HINT_APPEARANCE_DELAY_MS}ms after ${shownOverlay.debugName} was shown, showing hint for ${overlayToEducateAbout.debugName}"
            }
            education =
                when (overlayToEducateAbout) {
                    Overlays.NotificationsShade -> DualShadeEducationModel.HintForNotificationsShade
                    Overlays.QuickSettingsShade -> DualShadeEducationModel.HintForQuickSettingsShade
                    else -> DualShadeEducationModel.None
                }
            logD(TAG) {
                "Hint shown for ${overlayToEducateAbout.debugName} shown, waiting ${TOOLTIP_APPEARANCE_DELAY_MS}ms before escalation to tooltip"
                "${shownOverlay.debugName} shown, waiting ${TOOLTIP_APPEARANCE_DELAY_MS}ms before starting to educate about ${overlayToEducateAbout.debugName}"
            }

            delay(TOOLTIP_APPEARANCE_DELAY_MS)
            logD(TAG) {
                "Done waiting ${TOOLTIP_APPEARANCE_DELAY_MS}ms after hint was shown, escalating to tooltip for ${overlayToEducateAbout.debugName}"
                "Done waiting ${TOOLTIP_APPEARANCE_DELAY_MS}ms, showing tooltip for ${overlayToEducateAbout.debugName}"
            }
            education = DualShadeEducationModel.None
            education =
                when (overlayToEducateAbout) {
                    Overlays.NotificationsShade ->
                        DualShadeEducationModel.TooltipForNotificationsShade
                    Overlays.QuickSettingsShade ->
                        DualShadeEducationModel.TooltipForQuickSettingsShade
                    Overlays.NotificationsShade -> DualShadeEducationModel.ForNotificationsShade
                    Overlays.QuickSettingsShade -> DualShadeEducationModel.ForQuickSettingsShade
                    else -> DualShadeEducationModel.None
                }
        } catch (e: CancellationException) {
@@ -304,7 +285,6 @@ constructor(

    companion object {
        private const val TAG = "DualShadeEducation"
        @VisibleForTesting const val HINT_APPEARANCE_DELAY_MS = 5000L
        @VisibleForTesting const val TOOLTIP_APPEARANCE_DELAY_MS = 5000L
    }
}
+2 −17
Original line number Diff line number Diff line
@@ -18,22 +18,7 @@ package com.android.systemui.scene.domain.model

/** Enumerates the type of education still needed. */
enum class DualShadeEducationModel {
    /** Education isn't needed for either shade overlay. */
    None,
    /**
     * A hint is needed for the notifications shade overlay.
     *
     * A "hint" is something less intrusive than a tooltip; for example, a bounce animation.
     */
    HintForNotificationsShade,
    /**
     * A hint is needed for the quick settings shade overlay.
     *
     * A "hint" is something less intrusive than a tooltip; for example, a bounce animation.
     */
    HintForQuickSettingsShade,
    /** A tooltip is needed for the notifications shade overlay. */
    TooltipForNotificationsShade,
    /** A tooltip is needed for the quick settings shade overlay. */
    TooltipForQuickSettingsShade,
    ForNotificationsShade,
    ForQuickSettingsShade,
}
+2 −2
Original line number Diff line number Diff line
@@ -46,8 +46,8 @@ constructor(
    val visibleTooltip: DualShadeEducationalTooltipViewModel?
        get() =
            when (interactor.education) {
                DualShadeEducationModel.TooltipForNotificationsShade -> notificationsTooltip()
                DualShadeEducationModel.TooltipForQuickSettingsShade -> quickSettingsTooltip()
                DualShadeEducationModel.ForNotificationsShade -> notificationsTooltip()
                DualShadeEducationModel.ForQuickSettingsShade -> quickSettingsTooltip()
                else -> null
            }

Loading