From 4473652146efd7037fa720ef4ddd5f87b52524b2 Mon Sep 17 00:00:00 2001 From: Caitlin Cassidy Date: Thu, 7 Apr 2022 17:06:03 +0000 Subject: [PATCH] [Media TTT] Don't show scrubbing times if we don't have the prev or next button. Bug: 209656742 Test: manual (verified that no next or prev button -> scrubbing times not shown) Test: atest MediaControlPanelTest Change-Id: Iad44d2df9212ee34fa83f3272c2c1c2bd562df56 --- .../systemui/media/MediaControlPanel.java | 28 +++++++++---- .../systemui/media/MediaControlPanelTest.kt | 42 +++++++++++++++++++ 2 files changed, 63 insertions(+), 7 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java index aac28d1570ff8..d37f3ae67faed 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java @@ -630,7 +630,7 @@ public class MediaControlPanel { for (int id : SEMANTIC_ACTIONS_ALL) { ImageButton button = mMediaViewHolder.getAction(id); MediaAction action = semanticActions.getActionById(id); - setSemanticButton(button, action); + setSemanticButton(button, action, semanticActions); } } else { // Hide buttons that only appear for semantic actions @@ -699,7 +699,10 @@ public class MediaControlPanel { setVisibleAndAlpha(collapsedSet, button.getId(), visible && showInCompact); } - private void setSemanticButton(final ImageButton button, @Nullable MediaAction mediaAction) { + private void setSemanticButton( + final ImageButton button, + @Nullable MediaAction mediaAction, + MediaButton semanticActions) { AnimationBindHandler animHandler; if (button.getTag() == null) { animHandler = new AnimationBindHandler(); @@ -710,7 +713,7 @@ public class MediaControlPanel { animHandler.tryExecute(() -> { bindButtonWithAnimations(button, mediaAction, animHandler); - setSemanticButtonVisibleAndAlpha(button.getId(), mediaAction); + setSemanticButtonVisibleAndAlpha(button.getId(), mediaAction, semanticActions); }); } @@ -773,12 +776,14 @@ public class MediaControlPanel { private void setSemanticButtonVisibleAndAlpha( int buttonId, - MediaAction mediaAction) { + @Nullable MediaAction mediaAction, + MediaButton semanticActions) { ConstraintSet collapsedSet = mMediaViewController.getCollapsedLayout(); ConstraintSet expandedSet = mMediaViewController.getExpandedLayout(); boolean showInCompact = SEMANTIC_ACTIONS_COMPACT.contains(buttonId); boolean hideWhenScrubbing = SEMANTIC_ACTIONS_HIDE_WHEN_SCRUBBING.contains(buttonId); - boolean shouldBeHiddenDueToScrubbing = hideWhenScrubbing && mIsScrubbing; + boolean shouldBeHiddenDueToScrubbing = + scrubbingTimeViewsEnabled(semanticActions) && hideWhenScrubbing && mIsScrubbing; boolean visible = mediaAction != null && !shouldBeHiddenDueToScrubbing; setVisibleAndAlpha(expandedSet, buttonId, visible); @@ -791,7 +796,8 @@ public class MediaControlPanel { // Update visibilities of the scrubbing time views and the scrubbing-dependent buttons. bindScrubbingTime(mMediaData); SEMANTIC_ACTIONS_HIDE_WHEN_SCRUBBING.forEach((id) -> - setSemanticButtonVisibleAndAlpha(id, semanticActions.getActionById(id))); + setSemanticButtonVisibleAndAlpha( + id, semanticActions.getActionById(id), semanticActions)); // Trigger a state refresh so that we immediately update visibilities. mMediaViewController.refreshState(); } @@ -802,7 +808,7 @@ public class MediaControlPanel { int elapsedTimeId = mMediaViewHolder.getScrubbingElapsedTimeView().getId(); int totalTimeId = mMediaViewHolder.getScrubbingTotalTimeView().getId(); - boolean visible = data.getSemanticActions() != null && mIsScrubbing; + boolean visible = scrubbingTimeViewsEnabled(data.getSemanticActions()) && mIsScrubbing; setVisibleAndAlpha(expandedSet, elapsedTimeId, visible); setVisibleAndAlpha(expandedSet, totalTimeId, visible); // Never show in collapsed @@ -810,6 +816,14 @@ public class MediaControlPanel { setVisibleAndAlpha(collapsedSet, totalTimeId, false); } + private boolean scrubbingTimeViewsEnabled(@Nullable MediaButton semanticActions) { + // 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 + ); + } + // AnimationBindHandler is responsible for tracking the bound animation state and preventing // jank and conflicts due to media notifications arriving at any time during an animation. It // does this in two parts. diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt index dc48eb041c076..14db4bf81e146 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt @@ -413,10 +413,52 @@ public class MediaControlPanelTest : SysuiTestCase() { listener.onScrubbingChanged(true) mainExecutor.runAllReady() + verify(expandedSet, never()).setVisibility(eq(R.id.actionPrev), anyInt()) + verify(expandedSet, never()).setVisibility(eq(R.id.actionNext), anyInt()) verify(expandedSet, never()).setVisibility(eq(R.id.media_scrubbing_elapsed_time), anyInt()) verify(expandedSet, never()).setVisibility(eq(R.id.media_scrubbing_total_time), anyInt()) } + @Test + fun setIsScrubbing_noPrevButton_scrubbingTimesNotShown() { + val icon = context.getDrawable(android.R.drawable.ic_media_play) + val semanticActions = MediaButton( + prevOrCustom = null, + nextOrCustom = MediaAction(icon, {}, "next", null), + ) + 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.actionNext, View.VISIBLE) + verify(expandedSet).setVisibility(R.id.media_scrubbing_elapsed_time, View.GONE) + verify(expandedSet).setVisibility(R.id.media_scrubbing_total_time, View.GONE) + } + + @Test + fun setIsScrubbing_noNextButton_scrubbingTimesNotShown() { + val icon = context.getDrawable(android.R.drawable.ic_media_play) + val semanticActions = MediaButton( + prevOrCustom = MediaAction(icon, {}, "prev", null), + nextOrCustom = null, + ) + 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.VISIBLE) + verify(expandedSet).setVisibility(R.id.media_scrubbing_elapsed_time, View.GONE) + verify(expandedSet).setVisibility(R.id.media_scrubbing_total_time, View.GONE) + } + @Test fun setIsScrubbing_true_scrubbingViewsShownAndPrevNextHiddenOnlyInExpanded() { val icon = context.getDrawable(android.R.drawable.ic_media_play)