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
This commit is contained in:
Beth Thibodeau
2022-01-07 18:01:05 -05:00
parent 7bc21e772b
commit a8069694af
5 changed files with 71 additions and 3 deletions

View File

@@ -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 ==========================

View File

@@ -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)

View File

@@ -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<MediaAction> actionIcons = data.getActions();
List<Integer> 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<MediaAction>();
actionIcons.add(semanticActions.getStartCustom());
actionIcons.add(semanticActions.getPrevOrCustom());
actionIcons.add(semanticActions.getPlayOrPause());
actionIcons.add(semanticActions.getNextOrCustom());
actionIcons.add(semanticActions.getEndCustom());
actionsWhenCollapsed = new ArrayList<Integer>();
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];

View File

@@ -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)
}
}

View File

@@ -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"),