From a8069694af068da8419b6119275ec854afb113f4 Mon Sep 17 00:00:00 2001 From: Beth Thibodeau Date: Fri, 7 Jan 2022 18:01:05 -0500 Subject: [PATCH] Turn session actions on by default and add layout flag Adds a separate flag to enable the new media layout, which will also require the session actions flag to be enabled. Session actions flag will be enabled by default. If the new layout flag is off, this will show the actions in the old layout, ordered like: custom 2, previous, play, next, custom 1 Bug: 203800354 Bug: 209657555 Test: manual - flip flags, check controls Test: atest Change-Id: I0683d38939341631d6c48b266c0c35056344cfa6 --- .../src/com/android/systemui/flags/Flags.java | 3 +- .../systemui/media/MediaCarouselController.kt | 2 +- .../systemui/media/MediaControlPanel.java | 19 +++++++++ .../com/android/systemui/media/MediaFlags.kt | 8 ++++ .../systemui/media/MediaControlPanelTest.kt | 42 ++++++++++++++++++- 5 files changed, 71 insertions(+), 3 deletions(-) diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.java b/packages/SystemUI/src/com/android/systemui/flags/Flags.java index 726f8656767c0..306c26b9e9703 100644 --- a/packages/SystemUI/src/com/android/systemui/flags/Flags.java +++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.java @@ -123,7 +123,8 @@ public class Flags { /***************************************/ // 900 - media public static final BooleanFlag MEDIA_TAP_TO_TRANSFER = new BooleanFlag(900, false); - public static final BooleanFlag MEDIA_SESSION_ACTIONS = new BooleanFlag(901, false); + public static final BooleanFlag MEDIA_SESSION_ACTIONS = new BooleanFlag(901, true); + public static final BooleanFlag MEDIA_SESSION_LAYOUT = new BooleanFlag(902, false); // Pay no attention to the reflection behind the curtain. // ========================== Curtain ========================== diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt index ce3b443e677eb..da268236dbd5c 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt @@ -418,7 +418,7 @@ class MediaCarouselController @Inject constructor( .elementAtOrNull(mediaCarouselScrollHandler.visibleMediaIndex) if (existingPlayer == null) { var newPlayer = mediaControlPanelFactory.get() - if (mediaFlags.areMediaSessionActionsEnabled()) { + if (mediaFlags.useMediaSessionLayout()) { newPlayer.attachPlayer( PlayerSessionViewHolder.create(LayoutInflater.from(context), mediaContent), MediaViewController.TYPE.PLAYER_SESSION) diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java index 3c237223e31af..69a7ec3447aaf 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java +++ b/packages/SystemUI/src/com/android/systemui/media/MediaControlPanel.java @@ -61,6 +61,7 @@ import com.android.systemui.util.animation.TransitionLayout; import com.android.systemui.util.time.SystemClock; import java.net.URISyntaxException; +import java.util.ArrayList; import java.util.List; import java.util.concurrent.Executor; @@ -480,6 +481,24 @@ public class MediaControlPanel { List actionIcons = data.getActions(); List actionsWhenCollapsed = data.getActionsToShowInCompact(); + // If the session actions flag is enabled, but we're still using the regular layout, use + // the session actions anyways + if (mMediaFlags.areMediaSessionActionsEnabled() && data.getSemanticActions() != null) { + MediaButton semanticActions = data.getSemanticActions(); + + actionIcons = new ArrayList(); + actionIcons.add(semanticActions.getStartCustom()); + actionIcons.add(semanticActions.getPrevOrCustom()); + actionIcons.add(semanticActions.getPlayOrPause()); + actionIcons.add(semanticActions.getNextOrCustom()); + actionIcons.add(semanticActions.getEndCustom()); + + actionsWhenCollapsed = new ArrayList(); + actionsWhenCollapsed.add(1); + actionsWhenCollapsed.add(2); + actionsWhenCollapsed.add(3); + } + int i = 0; for (; i < actionIcons.size() && i < ACTION_IDS.length; i++) { int actionId = ACTION_IDS[i]; diff --git a/packages/SystemUI/src/com/android/systemui/media/MediaFlags.kt b/packages/SystemUI/src/com/android/systemui/media/MediaFlags.kt index b4a4b42d1509e..b9795f1265fa3 100644 --- a/packages/SystemUI/src/com/android/systemui/media/MediaFlags.kt +++ b/packages/SystemUI/src/com/android/systemui/media/MediaFlags.kt @@ -29,4 +29,12 @@ class MediaFlags @Inject constructor(private val featureFlags: FeatureFlags) { fun areMediaSessionActionsEnabled(): Boolean { return featureFlags.isEnabled(Flags.MEDIA_SESSION_ACTIONS) } + + /** + * Check whether media controls should use the new session-based layout + */ + fun useMediaSessionLayout(): Boolean { + return featureFlags.isEnabled(Flags.MEDIA_SESSION_ACTIONS) && + featureFlags.isEnabled(Flags.MEDIA_SESSION_LAYOUT) + } } \ No newline at end of file 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 7763e75ae40b1..140a395f1e273 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt +++ b/packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt @@ -202,6 +202,7 @@ public class MediaControlPanelTest : SysuiTestCase() { resumeAction = null) whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(false) + whenever(mediaFlags.useMediaSessionLayout()).thenReturn(false) } /** Mock view holder for the notification player */ @@ -301,8 +302,47 @@ public class MediaControlPanelTest : SysuiTestCase() { } @Test - fun bindSemanticActions() { + fun bindSemanticActionsOldLayout() { whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true) + whenever(mediaFlags.useMediaSessionLayout()).thenReturn(false) + + val icon = Icon.createWithResource(context, android.R.drawable.ic_media_play) + val semanticActions = MediaButton( + playOrPause = MediaAction(icon, Runnable {}, "play"), + nextOrCustom = MediaAction(icon, Runnable {}, "next"), + startCustom = MediaAction(icon, null, "custom 1"), + endCustom = MediaAction(icon, null, "custom 2") + ) + val state = mediaData.copy(semanticActions = semanticActions) + + player.attachPlayer(holder, MediaViewController.TYPE.PLAYER) + player.bindPlayer(state, PACKAGE) + + verify(expandedSet).setVisibility(R.id.action0, ConstraintSet.VISIBLE) + assertThat(action0.contentDescription).isEqualTo("custom 1") + assertThat(action0.isEnabled()).isFalse() + + verify(expandedSet).setVisibility(R.id.action1, ConstraintSet.INVISIBLE) + assertThat(action1.isEnabled()).isFalse() + + verify(expandedSet).setVisibility(R.id.action2, ConstraintSet.VISIBLE) + assertThat(action2.isEnabled()).isTrue() + assertThat(action2.contentDescription).isEqualTo("play") + + verify(expandedSet).setVisibility(R.id.action3, ConstraintSet.VISIBLE) + assertThat(action3.isEnabled()).isTrue() + assertThat(action3.contentDescription).isEqualTo("next") + + verify(expandedSet).setVisibility(R.id.action4, ConstraintSet.VISIBLE) + assertThat(action4.contentDescription).isEqualTo("custom 2") + assertThat(action4.isEnabled()).isFalse() + } + + @Test + fun bindSemanticActionsNewLayout() { + whenever(mediaFlags.areMediaSessionActionsEnabled()).thenReturn(true) + whenever(mediaFlags.useMediaSessionLayout()).thenReturn(true) + val icon = Icon.createWithResource(context, android.R.drawable.ic_media_play) val semanticActions = MediaButton( playOrPause = MediaAction(icon, Runnable {}, "play"),