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

Commit c5cda562 authored by Beth Thibodeau's avatar Beth Thibodeau
Browse files

Fix scrubbing time views visibility

- Always make relevant button views GONE when scrubbing
- Show scrubbing time views if there is a prev/next slot (not only when
  there is a visible button there)

Fixes: 380056189
Test: visual, with and without scene container flag
Test: MediaControlPanelTest, MediaControlViewModelTest
Flag: EXEMPT bugfix
Change-Id: Ib1ef16bdb9df93d62773d23ab7a2904b008d0eca
parent a7656c9a
Loading
Loading
Loading
Loading
+28 −1
Original line number Diff line number Diff line
@@ -16,21 +16,23 @@

package com.android.systemui.media.controls.ui.viewmodel

import android.R
import android.content.packageManager
import android.content.pm.ApplicationInfo
import android.media.MediaMetadata
import android.media.session.MediaSession
import android.media.session.PlaybackState
import androidx.constraintlayout.widget.ConstraintSet
import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.coroutines.collectLastValue
import com.android.systemui.kosmos.testScope
import com.android.systemui.media.controls.domain.pipeline.mediaDataFilter
import com.android.systemui.media.controls.shared.model.MediaButton
import com.android.systemui.media.controls.shared.model.MediaData
import com.android.systemui.media.controls.shared.model.MediaDeviceData
import com.android.systemui.media.controls.util.mediaInstanceId
import com.android.systemui.res.R
import com.android.systemui.statusbar.notificationLockscreenUserManager
import com.android.systemui.testKosmos
import com.google.common.truth.Truth.assertThat
@@ -132,6 +134,31 @@ class MediaControlViewModelTest : SysuiTestCase() {
            assertThat(underTest.setPlayer(playerModel!!)).isTrue()
        }

    @Test
    fun reservedButtons_showScrubbingTimes() =
        testScope.runTest {
            val playerModel by collectLastValue(underTest.player)
            val mediaData =
                initMediaData(ARTIST, TITLE)
                    .copy(semanticActions = MediaButton(reserveNext = true, reservePrev = true))

            mediaDataFilter.onMediaDataLoaded(KEY, KEY, mediaData)

            assertThat(playerModel?.actionButtons).isNotNull()
            assertThat(playerModel!!.useSemanticActions).isTrue()
            assertThat(playerModel!!.canShowTime).isTrue()

            val buttons = playerModel!!.actionButtons

            val prevButton = buttons.find { it.buttonId == R.id.actionPrev }!!
            assertThat(prevButton.notVisibleValue).isEqualTo(ConstraintSet.GONE)
            assertThat(prevButton.isVisibleWhenScrubbing).isEqualTo(false)

            val nextButton = buttons.find { it.buttonId == R.id.actionNext }!!
            assertThat(nextButton.notVisibleValue).isEqualTo(ConstraintSet.GONE)
            assertThat(nextButton.isVisibleWhenScrubbing).isEqualTo(false)
        }

    private fun initMediaData(artist: String, title: String): MediaData {
        val device = MediaDeviceData(true, null, DEVICE_NAME, null, showBroadcastButton = true)

+6 −3
Original line number Diff line number Diff line
@@ -1369,8 +1369,9 @@ public class MediaControlPanel {
        boolean visible = mediaAction != null && !shouldBeHiddenDueToScrubbing;

        int notVisibleValue;
        if ((buttonId == R.id.actionPrev && semanticActions.getReservePrev())
                || (buttonId == R.id.actionNext && semanticActions.getReserveNext())) {
        if (!shouldBeHiddenDueToScrubbing
                && ((buttonId == R.id.actionPrev && semanticActions.getReservePrev())
                    || (buttonId == R.id.actionNext && semanticActions.getReserveNext()))) {
            notVisibleValue = ConstraintSet.INVISIBLE;
            mMediaViewHolder.getAction(buttonId).setFocusable(visible);
            mMediaViewHolder.getAction(buttonId).setClickable(visible);
@@ -1408,7 +1409,9 @@ public class MediaControlPanel {
        // The scrubbing time views replace the SEMANTIC_ACTIONS_HIDE_WHEN_SCRUBBING action views,
        // so we should only allow scrubbing times to be shown if those action views are present.
        return semanticActions != null && SEMANTIC_ACTIONS_HIDE_WHEN_SCRUBBING.stream().allMatch(
                id -> semanticActions.getActionById(id) != null
                id -> (semanticActions.getActionById(id) != null
                        || ((id == R.id.actionPrev && semanticActions.getReservePrev())
                            || (id == R.id.actionNext && semanticActions.getReserveNext())))
        );
    }

+8 −3
Original line number Diff line number Diff line
@@ -316,8 +316,11 @@ class MediaControlViewModel(
            isVisibleWhenScrubbing = !shouldHideWhenScrubbing,
            notVisibleValue =
                if (
                    (buttonId == R.id.actionPrev && model.semanticActionButtons!!.reservePrev) ||
                        (buttonId == R.id.actionNext && model.semanticActionButtons!!.reserveNext)
                    !shouldHideWhenScrubbing &&
                        ((buttonId == R.id.actionPrev &&
                            model.semanticActionButtons!!.reservePrev) ||
                            (buttonId == R.id.actionNext &&
                                model.semanticActionButtons!!.reserveNext))
                ) {
                    ConstraintSet.INVISIBLE
                } else {
@@ -382,7 +385,9 @@ class MediaControlViewModel(
        // so we should only allow scrubbing times to be shown if those action views are present.
        return semanticActions?.let {
            SEMANTIC_ACTIONS_HIDE_WHEN_SCRUBBING.stream().allMatch { id: Int ->
                semanticActions.getActionById(id) != null
                semanticActions.getActionById(id) != null ||
                    (id == R.id.actionPrev && semanticActions.reservePrev ||
                        id == R.id.actionNext && semanticActions.reserveNext)
            }
        } ?: false
    }
+62 −39
Original line number Diff line number Diff line
@@ -247,7 +247,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
            mContext,
            0,
            intent.setPackage(mContext.packageName),
            PendingIntent.FLAG_MUTABLE
            PendingIntent.FLAG_MUTABLE,
        )

    @JvmField @Rule val mockito = MockitoJUnit.rule()
@@ -294,7 +294,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                override fun loadAnimator(
                    animId: Int,
                    otionInterpolator: Interpolator,
                    vararg targets: View
                    vararg targets: View,
                ): AnimatorSet {
                    return mockAnimator
                }
@@ -323,7 +323,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                packageName = PACKAGE,
                instanceId = instanceId,
                recommendations = listOf(smartspaceAction, smartspaceAction, smartspaceAction),
                cardAction = smartspaceAction
                cardAction = smartspaceAction,
            )
    }

@@ -370,7 +370,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                packageName = PACKAGE,
                token = session.sessionToken,
                device = device,
                instanceId = instanceId
                instanceId = instanceId,
            )
    }

@@ -416,7 +416,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                        action1.id,
                        action2.id,
                        action3.id,
                        action4.id
                        action4.id,
                    )
            }

@@ -536,7 +536,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                playOrPause = MediaAction(icon, Runnable {}, "play", bg),
                nextOrCustom = MediaAction(icon, Runnable {}, "next", bg),
                custom0 = MediaAction(icon, null, "custom 0", bg),
                custom1 = MediaAction(icon, null, "custom 1", bg)
                custom1 = MediaAction(icon, null, "custom 1", bg),
            )
        val state = mediaData.copy(semanticActions = semanticActions)
        player.attachPlayer(viewHolder)
@@ -590,7 +590,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                custom0 = MediaAction(icon, null, "custom 0", bg),
                custom1 = MediaAction(icon, null, "custom 1", bg),
                false,
                true
                true,
            )
        val state = mediaData.copy(semanticActions = semanticActions)

@@ -622,7 +622,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                custom0 = MediaAction(icon, null, "custom 0", bg),
                custom1 = MediaAction(icon, null, "custom 1", bg),
                true,
                false
                false,
            )
        val state = mediaData.copy(semanticActions = semanticActions)

@@ -760,7 +760,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
        val semanticActions =
            MediaButton(
                playOrPause = MediaAction(icon, Runnable {}, "play", null),
                nextOrCustom = MediaAction(icon, Runnable {}, "next", null)
                nextOrCustom = MediaAction(icon, Runnable {}, "next", null),
            )
        val state = mediaData.copy(semanticActions = semanticActions)

@@ -850,7 +850,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
        val semanticActions =
            MediaButton(
                prevOrCustom = MediaAction(icon, {}, "prev", null),
                nextOrCustom = MediaAction(icon, {}, "next", null)
                nextOrCustom = MediaAction(icon, {}, "next", null),
            )
        val state = mediaData.copy(semanticActions = semanticActions)

@@ -921,7 +921,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
        val semanticActions =
            MediaButton(
                prevOrCustom = MediaAction(icon, {}, "prev", null),
                nextOrCustom = MediaAction(icon, {}, "next", null)
                nextOrCustom = MediaAction(icon, {}, "next", null),
            )
        val state = mediaData.copy(semanticActions = semanticActions)
        player.attachPlayer(viewHolder)
@@ -944,7 +944,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
        val semanticActions =
            MediaButton(
                prevOrCustom = MediaAction(icon, {}, "prev", null),
                nextOrCustom = MediaAction(icon, {}, "next", null)
                nextOrCustom = MediaAction(icon, {}, "next", null),
            )
        val state = mediaData.copy(semanticActions = semanticActions)

@@ -965,6 +965,29 @@ public class MediaControlPanelTest : SysuiTestCase() {
        verify(expandedSet).setVisibility(R.id.actionNext, ConstraintSet.VISIBLE)
    }

    @Test
    fun setIsScrubbing_reservedButtonSpaces_scrubbingTimesShown() {
        val semanticActions =
            MediaButton(
                prevOrCustom = null,
                nextOrCustom = null,
                reserveNext = true,
                reservePrev = true,
            )
        val state = mediaData.copy(semanticActions = semanticActions)
        player.attachPlayer(viewHolder)
        player.bindPlayer(state, PACKAGE)
        reset(expandedSet)

        getScrubbingChangeListener().onScrubbingChanged(true)
        mainExecutor.runAllReady()

        verify(expandedSet).setVisibility(R.id.actionPrev, View.GONE)
        verify(expandedSet).setVisibility(R.id.actionNext, View.GONE)
        verify(expandedSet).setVisibility(R.id.media_scrubbing_elapsed_time, View.VISIBLE)
        verify(expandedSet).setVisibility(R.id.media_scrubbing_total_time, View.VISIBLE)
    }

    @Test
    fun bind_resumeState_withProgress() {
        val progress = 0.5
@@ -1009,13 +1032,13 @@ public class MediaControlPanelTest : SysuiTestCase() {
                MediaNotificationAction(true, actionIntent = pendingIntent, icon, "play"),
                MediaNotificationAction(true, actionIntent = null, icon, "next"),
                MediaNotificationAction(true, actionIntent = null, icon, "custom 0"),
                MediaNotificationAction(true, actionIntent = pendingIntent, icon, "custom 1")
                MediaNotificationAction(true, actionIntent = pendingIntent, icon, "custom 1"),
            )
        val state =
            mediaData.copy(
                actions = actions,
                actionsToShowInCompact = listOf(1, 2),
                semanticActions = null
                semanticActions = null,
            )

        player.attachPlayer(viewHolder)
@@ -1701,7 +1724,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                MediaNotificationAction(true, actionIntent = pendingIntent, null, "action 1"),
                MediaNotificationAction(true, actionIntent = pendingIntent, null, "action 2"),
                MediaNotificationAction(true, actionIntent = pendingIntent, null, "action 3"),
                MediaNotificationAction(true, actionIntent = pendingIntent, null, "action 4")
                MediaNotificationAction(true, actionIntent = pendingIntent, null, "action 4"),
            )
        val data = mediaData.copy(actions = actions)

@@ -1720,7 +1743,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                MediaNotificationAction(true, actionIntent = pendingIntent, null, "action 1"),
                MediaNotificationAction(true, actionIntent = pendingIntent, null, "action 2"),
                MediaNotificationAction(true, actionIntent = pendingIntent, null, "action 3"),
                MediaNotificationAction(true, actionIntent = pendingIntent, null, "action 4")
                MediaNotificationAction(true, actionIntent = pendingIntent, null, "action 4"),
            )
        val data = mediaData.copy(actions = actions)

@@ -1739,7 +1762,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                MediaNotificationAction(true, actionIntent = pendingIntent, null, "action 1"),
                MediaNotificationAction(true, actionIntent = pendingIntent, null, "action 2"),
                MediaNotificationAction(true, actionIntent = pendingIntent, null, "action 3"),
                MediaNotificationAction(true, actionIntent = pendingIntent, null, "action 4")
                MediaNotificationAction(true, actionIntent = pendingIntent, null, "action 4"),
            )
        val data = mediaData.copy(actions = actions)

@@ -2021,7 +2044,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                            .setSubtitle(subtitle3)
                            .setIcon(icon)
                            .setExtras(Bundle.EMPTY)
                            .build()
                            .build(),
                    )
            )
        player.bindRecommendation(data)
@@ -2047,7 +2070,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                            .setIcon(
                                Icon.createWithResource(
                                    context,
                                    com.android.settingslib.R.drawable.ic_1x_mobiledata
                                    com.android.settingslib.R.drawable.ic_1x_mobiledata,
                                )
                            )
                            .setExtras(Bundle.EMPTY)
@@ -2084,7 +2107,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                            .setSubtitle("fake subtitle")
                            .setIcon(icon)
                            .setExtras(Bundle.EMPTY)
                            .build()
                            .build(),
                    )
            )
        player.bindRecommendation(data)
@@ -2119,7 +2142,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                            .setSubtitle("")
                            .setIcon(icon)
                            .setExtras(Bundle.EMPTY)
                            .build()
                            .build(),
                    )
            )
        player.bindRecommendation(data)
@@ -2142,7 +2165,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                            .setIcon(
                                Icon.createWithResource(
                                    context,
                                    com.android.settingslib.R.drawable.ic_1x_mobiledata
                                    com.android.settingslib.R.drawable.ic_1x_mobiledata,
                                )
                            )
                            .setExtras(Bundle.EMPTY)
@@ -2157,11 +2180,11 @@ public class MediaControlPanelTest : SysuiTestCase() {
                            .setIcon(
                                Icon.createWithResource(
                                    context,
                                    com.android.settingslib.R.drawable.ic_3g_mobiledata
                                    com.android.settingslib.R.drawable.ic_3g_mobiledata,
                                )
                            )
                            .setExtras(Bundle.EMPTY)
                            .build()
                            .build(),
                    )
            )

@@ -2185,7 +2208,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                            .setIcon(
                                Icon.createWithResource(
                                    context,
                                    com.android.settingslib.R.drawable.ic_1x_mobiledata
                                    com.android.settingslib.R.drawable.ic_1x_mobiledata,
                                )
                            )
                            .setExtras(Bundle.EMPTY)
@@ -2200,11 +2223,11 @@ public class MediaControlPanelTest : SysuiTestCase() {
                            .setIcon(
                                Icon.createWithResource(
                                    context,
                                    com.android.settingslib.R.drawable.ic_3g_mobiledata
                                    com.android.settingslib.R.drawable.ic_3g_mobiledata,
                                )
                            )
                            .setExtras(Bundle.EMPTY)
                            .build()
                            .build(),
                    )
            )

@@ -2245,7 +2268,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                            .setSubtitle("subtitle1")
                            .setIcon(albumArt)
                            .setExtras(Bundle.EMPTY)
                            .build()
                            .build(),
                    )
            )

@@ -2268,7 +2291,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
            Bundle().apply {
                putInt(
                    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS,
                    MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED
                    MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED,
                )
                putDouble(MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.5)
            }
@@ -2290,7 +2313,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                            .setSubtitle("subtitle1")
                            .setIcon(albumArt)
                            .setExtras(Bundle.EMPTY)
                            .build()
                            .build(),
                    )
            )

@@ -2328,7 +2351,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                            .setSubtitle("subtitle1")
                            .setIcon(albumArt)
                            .setExtras(Bundle.EMPTY)
                            .build()
                            .build(),
                    )
            )

@@ -2381,7 +2404,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                            .setSubtitle("subtitle1")
                            .setIcon(albumArt)
                            .setExtras(Bundle.EMPTY)
                            .build()
                            .build(),
                    )
            )

@@ -2444,7 +2467,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                        icon = null,
                        action = {},
                        contentDescription = "play",
                        background = null
                        background = null,
                    )
            )
        val data = mediaData.copy(semanticActions = semanticActions)
@@ -2465,7 +2488,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                        icon = null,
                        action = {},
                        contentDescription = "play",
                        background = null
                        background = null,
                    )
            )
        val data = mediaData.copy(semanticActions = semanticActions)
@@ -2498,7 +2521,7 @@ public class MediaControlPanelTest : SysuiTestCase() {
                        icon = null,
                        action = {},
                        contentDescription = "play",
                        background = null
                        background = null,
                    )
            )
        val data = mediaData.copy(semanticActions = semanticActions)
@@ -2530,8 +2553,8 @@ public class MediaControlPanelTest : SysuiTestCase() {
                        icon = null,
                        action = {},
                        contentDescription = "custom0",
                        background = null
                    ),
                        background = null,
                    )
            )
        val data = mediaData.copy(semanticActions = semanticActions)
        player.attachPlayer(viewHolder)
@@ -2553,8 +2576,8 @@ public class MediaControlPanelTest : SysuiTestCase() {
                        icon = null,
                        action = {},
                        contentDescription = "custom0",
                        background = null
                    ),
                        background = null,
                    )
            )
        val data = mediaData.copy(semanticActions = semanticActions)
        player.attachPlayer(viewHolder)