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

Commit 9cc5e239 authored by Alexandr Shabalin's avatar Alexandr Shabalin Committed by Android (Google) Code Review
Browse files

Merge "Prevent making unnecessary requestDeviceSuggestion() calls." into main

parents 0b881acf fcf5804e
Loading
Loading
Loading
Loading
+17 −4
Original line number Original line Diff line number Diff line
@@ -67,7 +67,7 @@ class MediaCarouselScrollHandlerTest : SysuiTestCase() {
    @Mock lateinit var seekBarUpdateListener: (visibleToUser: Boolean) -> Unit
    @Mock lateinit var seekBarUpdateListener: (visibleToUser: Boolean) -> Unit
    @Mock lateinit var closeGuts: (immediate: Boolean) -> Unit
    @Mock lateinit var closeGuts: (immediate: Boolean) -> Unit
    @Mock lateinit var falsingManager: FalsingManager
    @Mock lateinit var falsingManager: FalsingManager
    @Mock lateinit var onCarouselVisibleToUser: () -> Unit
    @Mock lateinit var onVisibleCardChanged: () -> Unit
    @Mock lateinit var logger: MediaUiEventLogger
    @Mock lateinit var logger: MediaUiEventLogger
    @Mock lateinit var contentContainer: ViewGroup
    @Mock lateinit var contentContainer: ViewGroup
    @Mock lateinit var settingsButton: View
    @Mock lateinit var settingsButton: View
@@ -97,7 +97,7 @@ class MediaCarouselScrollHandlerTest : SysuiTestCase() {
                seekBarUpdateListener,
                seekBarUpdateListener,
                closeGuts,
                closeGuts,
                falsingManager,
                falsingManager,
                onCarouselVisibleToUser,
                onVisibleCardChanged,
                logger,
                logger,
            )
            )
        mediaCarouselScrollHandler.playerWidthPlusPadding = carouselWidth
        mediaCarouselScrollHandler.playerWidthPlusPadding = carouselWidth
@@ -257,7 +257,7 @@ class MediaCarouselScrollHandlerTest : SysuiTestCase() {
    }
    }


    @Test
    @Test
    fun testCarouselScrollToNewIndex_onCarouselVisibleToUser() {
    fun testCarouselScrollToNewIndex_exactScroll_onVisibleCardChanged() {
        setupMediaContainer(visibleIndex = 0)
        setupMediaContainer(visibleIndex = 0)
        whenever(mediaCarousel.relativeScrollX).thenReturn(carouselWidth)
        whenever(mediaCarousel.relativeScrollX).thenReturn(carouselWidth)
        mediaCarouselScrollHandler.visibleToUser = true
        mediaCarouselScrollHandler.visibleToUser = true
@@ -266,7 +266,20 @@ class MediaCarouselScrollHandlerTest : SysuiTestCase() {


        captor.value.onScrollChange(null, 0, 0, 0, 0)
        captor.value.onScrollChange(null, 0, 0, 0, 0)


        verify(onCarouselVisibleToUser).invoke()
        verify(onVisibleCardChanged).invoke()
    }

    @Test
    fun testCarouselScrollToNewIndex_partialScroll_noCallbackInvoked() {
        setupMediaContainer(visibleIndex = 0)
        whenever(mediaCarousel.relativeScrollX).thenReturn(carouselWidth + 15)
        mediaCarouselScrollHandler.visibleToUser = true
        val captor = ArgumentCaptor.forClass(View.OnScrollChangeListener::class.java)
        verify(mediaCarousel).setOnScrollChangeListener(captor.capture())

        captor.value.onScrollChange(null, 0, 0, 0, 0)

        verify(onVisibleCardChanged, never()).invoke()
    }
    }


    private fun setupMediaContainer(visibleIndex: Int, showsSettingsButton: Boolean = true) {
    private fun setupMediaContainer(visibleIndex: Int, showsSettingsButton: Boolean = true) {
+38 −4
Original line number Original line Diff line number Diff line
@@ -60,6 +60,7 @@ import com.android.systemui.keyguard.shared.model.TransitionState
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.lifecycle.repeatWhenAttached
import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.media.controls.domain.pipeline.MediaDataManager
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.ui.controller.MediaPlayerData.visiblePlayerKeys
import com.android.systemui.media.controls.ui.view.MediaCarouselScrollHandler
import com.android.systemui.media.controls.ui.view.MediaCarouselScrollHandler
import com.android.systemui.media.controls.ui.view.MediaHostState
import com.android.systemui.media.controls.ui.view.MediaHostState
import com.android.systemui.media.controls.ui.view.MediaScrollView
import com.android.systemui.media.controls.ui.view.MediaScrollView
@@ -155,6 +156,9 @@ constructor(
    /** Are we currently disabling scrolling, only allowing the first media session to show */
    /** Are we currently disabling scrolling, only allowing the first media session to show */
    private var currentlyDisableScrolling: Boolean = false
    private var currentlyDisableScrolling: Boolean = false


    /** A key for the last player card that is completely visible */
    private var lastFullyVisiblePlayerKey: String? = null

    /**
    /**
     * The desired location where we'll be at the end of the transformation. Usually this matches
     * The desired location where we'll be at the end of the transformation. Usually this matches
     * the end location, except when we're still waiting on a state update call.
     * the end location, except when we're still waiting on a state update call.
@@ -336,7 +340,7 @@ constructor(
                this::updateSeekbarListening,
                this::updateSeekbarListening,
                this::closeGuts,
                this::closeGuts,
                falsingManager,
                falsingManager,
                this::onCarouselVisibleToUser,
                this::onVisibleCardChanged,
                logger,
                logger,
            )
            )
        carouselLocale = context.resources.configuration.locales.get(0)
        carouselLocale = context.resources.configuration.locales.get(0)
@@ -1052,18 +1056,48 @@ constructor(
        layout(0, 0, width, height)
        layout(0, 0, width, height)
    }
    }


    /** Triggered whenever carousel becomes visible, e.g. on swipe down the notification shade. */
    fun onCarouselVisibleToUser() {
    fun onCarouselVisibleToUser() {
        if (!enableSuggestedDeviceUi()) {
            return
        }
        onCardVisibilityChanged()
    }

    /** Triggered whenever carousel's scroll position changes, revealing a new card.  */
    fun onVisibleCardChanged() {
        if (!enableSuggestedDeviceUi()) {
            return
        }
        val newVisiblePlayerKey =
            visiblePlayerKeys().elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex)?.key
        if (newVisiblePlayerKey != lastFullyVisiblePlayerKey) {
            lastFullyVisiblePlayerKey = newVisiblePlayerKey
            if (newVisiblePlayerKey != null) {
                onCardVisibilityChanged()
            }
        }
    }

    /**
     * Triggered whenever card becomes visible either due to the carousel being visible or the card
     * visibility changed within the carousel.
     */
    private fun onCardVisibilityChanged() {
        val isCarouselVisible = mediaCarouselScrollHandler.visibleToUser
        val visibleMediaIndex = mediaCarouselScrollHandler.visibleMediaIndex
        debugLogger.logCardVisibilityChanged(isCarouselVisible, visibleMediaIndex)

        if (
        if (
            !enableSuggestedDeviceUi() ||
            !enableSuggestedDeviceUi() ||
                !mediaCarouselScrollHandler.visibleToUser ||
                !isCarouselVisible ||
                MediaPlayerData.mediaData().all { it.second.resumption }
                MediaPlayerData.mediaData().all { it.second.resumption }
        ) {
        ) {
            return
            return
        }
        }
        val visibleMediaIndex = mediaCarouselScrollHandler.visibleMediaIndex
        if (MediaPlayerData.players().size > visibleMediaIndex) {
        if (MediaPlayerData.players().size > visibleMediaIndex) {
            val mediaControlPanel = MediaPlayerData.getMediaControlPanel(visibleMediaIndex)
            val mediaControlPanel = MediaPlayerData.getMediaControlPanel(visibleMediaIndex)
            mediaControlPanel?.onSuggestionSpaceVisible()
            mediaControlPanel?.onPanelFullyVisible()
        }
        }
    }
    }


+12 −0
Original line number Original line Diff line number Diff line
@@ -109,6 +109,18 @@ constructor(@MediaCarouselControllerLog private val buffer: LogBuffer) {
            { "media carousel($str1), width: $int1 height: $int2, location:$long1" },
            { "media carousel($str1), width: $int1 height: $int2, location:$long1" },
        )
        )
    }
    }

    fun logCardVisibilityChanged(carouselVisible: Boolean, visibleMediaIndex: Int) {
        buffer.log(
            TAG,
            LogLevel.DEBUG,
            {
                bool1 = carouselVisible
                int1 = visibleMediaIndex
            },
            { "card visibility changed, isVisible: $bool1, index: $int1" },
        )
    }
}
}


private const val TAG = "MediaCarouselCtlrLog"
private const val TAG = "MediaCarouselCtlrLog"
+2 −2
Original line number Original line Diff line number Diff line
@@ -606,9 +606,9 @@ public class MediaControlPanel {
    }
    }


    /**
    /**
     * Should be called when the space that holds device suggestions becomes visible to the user.
     * Called when the panel becomes fully visible.
     */
     */
    public void onSuggestionSpaceVisible() {
    public void onPanelFullyVisible() {
        if (!Flags.enableSuggestedDeviceUi()) {
        if (!Flags.enableSuggestedDeviceUi()) {
            return;
            return;
        }
        }
+5 −2
Original line number Original line Diff line number Diff line
@@ -64,7 +64,7 @@ class MediaCarouselScrollHandler(
    private var seekBarUpdateListener: (visibleToUser: Boolean) -> Unit,
    private var seekBarUpdateListener: (visibleToUser: Boolean) -> Unit,
    private val closeGuts: (immediate: Boolean) -> Unit,
    private val closeGuts: (immediate: Boolean) -> Unit,
    private val falsingManager: FalsingManager,
    private val falsingManager: FalsingManager,
    private val onCarouselVisibleToUser: () -> Unit,
    private val onVisibleCardChanged: () -> Unit,
    private val logger: MediaUiEventLogger,
    private val logger: MediaUiEventLogger,
) {
) {
    /** Trace state logger for media carousel visibility */
    /** Trace state logger for media carousel visibility */
@@ -548,7 +548,10 @@ class MediaCarouselScrollHandler(
            val visible = (i == visibleMediaIndex) || ((i == (visibleMediaIndex + 1)) && scrolledIn)
            val visible = (i == visibleMediaIndex) || ((i == (visibleMediaIndex + 1)) && scrolledIn)
            view.visibility = if (visible) View.VISIBLE else View.INVISIBLE
            view.visibility = if (visible) View.VISIBLE else View.INVISIBLE
        }
        }
        onCarouselVisibleToUser()
        if (!scrolledIn) {
            // Ignore events with a partial scroll, only proceed if the card is fully visible.
            onVisibleCardChanged()
        }
    }
    }


    /**
    /**
Loading