diff options
| author | 2024-12-10 13:25:50 -0600 | |
|---|---|---|
| committer | 2024-12-12 15:02:40 -0600 | |
| commit | c5cda562ca74d74e10d5cd952a8581c3f86550a9 (patch) | |
| tree | b8dc4410a19021fda65796ed1c85a6fe691e1ef7 | |
| parent | a7656c9a3f3b6176775eb54a13da387324dc6517 (diff) | |
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
4 files changed, 104 insertions, 46 deletions
diff --git a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModelTest.kt b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModelTest.kt index 9edd62a8a784..6a2aae175d80 100644 --- a/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModelTest.kt +++ b/packages/SystemUI/multivalentTests/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModelTest.kt @@ -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) diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java index 70ca82492775..dccf61d4e6c7 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/controller/MediaControlPanel.java @@ -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()))) ); } diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt index 4e97f2015c12..61e4d95a88e6 100644 --- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt +++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/viewmodel/MediaControlViewModel.kt @@ -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 } diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt index 68a5d9361046..9543032ef5ec 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/controller/MediaControlPanelTest.kt @@ -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) @@ -966,6 +966,29 @@ public class MediaControlPanelTest : SysuiTestCase() { } @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 val state = mediaData.copy(resumption = true, resumeProgress = progress) @@ -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) |