mirror of
https://github.com/androidx/media.git
synced 2025-04-29 22:36:54 +08:00
Compat logic for MediaController.getCustomLayout
When a new media session sets media button preferences, we need to "translate" them back to a custom layout to ensure the user preferences are represented as closely as possible when the controller uses the old button placement rules. PiperOrigin-RevId: 693306153
This commit is contained in:
parent
9fb4ed91b6
commit
12cb803486
@ -410,6 +410,8 @@ public class MediaController implements Player {
|
||||
* Called when the {@linkplain #getCustomLayout() custom layout} changed.
|
||||
*
|
||||
* <p>This method will be deprecated, prefer to use {@link #onMediaButtonPreferencesChanged}.
|
||||
* Note that the media button preferences use {@link CommandButton#slots} to define the allowed
|
||||
* button placement.
|
||||
*
|
||||
* <p>The custom layout can change when either the session {@linkplain
|
||||
* MediaSession#setCustomLayout changes the custom layout}, or when the session {@linkplain
|
||||
@ -1116,6 +1118,8 @@ public class MediaController implements Player {
|
||||
* Returns the custom layout.
|
||||
*
|
||||
* <p>This method will be deprecated, prefer to use {@link #getMediaButtonPreferences()} instead.
|
||||
* Note that the media button preferences use {@link CommandButton#slots} to define the allowed
|
||||
* button placement.
|
||||
*
|
||||
* <p>After being connected, a change of the custom layout is reported with {@link
|
||||
* Listener#onCustomLayoutChanged(MediaController, List)}.
|
||||
@ -1127,7 +1131,8 @@ public class MediaController implements Player {
|
||||
*/
|
||||
@UnstableApi
|
||||
public final ImmutableList<CommandButton> getCustomLayout() {
|
||||
return getMediaButtonPreferences();
|
||||
verifyApplicationThread();
|
||||
return isConnected() ? impl.getCustomLayout() : ImmutableList.of();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2208,6 +2213,8 @@ public class MediaController implements Player {
|
||||
|
||||
ImmutableList<CommandButton> getMediaButtonPreferences();
|
||||
|
||||
ImmutableList<CommandButton> getCustomLayout();
|
||||
|
||||
ImmutableList<CommandButton> getCommandButtonsForMediaItem(MediaItem mediaItem);
|
||||
|
||||
Bundle getSessionExtras();
|
||||
|
@ -93,7 +93,6 @@ import com.google.common.util.concurrent.MoreExecutors;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.concurrent.CancellationException;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
@ -128,6 +127,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
private ImmutableList<CommandButton> customLayoutOriginal;
|
||||
private ImmutableList<CommandButton> mediaButtonPreferencesOriginal;
|
||||
private ImmutableList<CommandButton> resolvedMediaButtonPreferences;
|
||||
private ImmutableList<CommandButton> resolvedCustomLayout;
|
||||
private ImmutableMap<String, CommandButton> commandButtonsForMediaItemsMap;
|
||||
private SessionCommands sessionCommands;
|
||||
private Commands playerCommandsFromSession;
|
||||
@ -158,6 +158,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
customLayoutOriginal = ImmutableList.of();
|
||||
mediaButtonPreferencesOriginal = ImmutableList.of();
|
||||
resolvedMediaButtonPreferences = ImmutableList.of();
|
||||
resolvedCustomLayout = ImmutableList.of();
|
||||
commandButtonsForMediaItemsMap = ImmutableMap.of();
|
||||
playerCommandsFromSession = Commands.EMPTY;
|
||||
playerCommandsFromPlayer = Commands.EMPTY;
|
||||
@ -751,6 +752,11 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
return resolvedMediaButtonPreferences;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableList<CommandButton> getCustomLayout() {
|
||||
return resolvedCustomLayout;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableList<CommandButton> getCommandButtonsForMediaItem(MediaItem mediaItem) {
|
||||
ImmutableList<String> supportedActions = mediaItem.mediaMetadata.supportedCommands;
|
||||
@ -2662,6 +2668,9 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
sessionCommands,
|
||||
intersectedPlayerCommands,
|
||||
result.sessionExtras);
|
||||
resolvedCustomLayout =
|
||||
resolveCustomLayout(
|
||||
resolvedMediaButtonPreferences, result.sessionExtras, intersectedPlayerCommands);
|
||||
ImmutableMap.Builder<String, CommandButton> commandButtonsForMediaItems =
|
||||
new ImmutableMap.Builder<>();
|
||||
for (int i = 0; i < result.commandButtonsForMediaItems.size(); i++) {
|
||||
@ -2842,8 +2851,10 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
!Util.areEqual(intersectedPlayerCommands, prevIntersectedPlayerCommands);
|
||||
}
|
||||
boolean mediaButtonPreferencesChanged = false;
|
||||
boolean customLayoutChanged = false;
|
||||
if (sessionCommandsChanged || intersectedPlayerCommandsChanged) {
|
||||
ImmutableList<CommandButton> oldMediaButtonPreferences = resolvedMediaButtonPreferences;
|
||||
ImmutableList<CommandButton> oldCustomLayout = resolvedCustomLayout;
|
||||
resolvedMediaButtonPreferences =
|
||||
resolveMediaButtonPreferences(
|
||||
mediaButtonPreferencesOriginal,
|
||||
@ -2851,8 +2862,12 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
sessionCommands,
|
||||
intersectedPlayerCommands,
|
||||
sessionExtras);
|
||||
resolvedCustomLayout =
|
||||
resolveCustomLayout(
|
||||
resolvedMediaButtonPreferences, sessionExtras, intersectedPlayerCommands);
|
||||
mediaButtonPreferencesChanged =
|
||||
!resolvedMediaButtonPreferences.equals(oldMediaButtonPreferences);
|
||||
customLayoutChanged = !resolvedCustomLayout.equals(oldCustomLayout);
|
||||
}
|
||||
if (intersectedPlayerCommandsChanged) {
|
||||
listeners.sendEvent(
|
||||
@ -2865,14 +2880,17 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
listener ->
|
||||
listener.onAvailableSessionCommandsChanged(getInstance(), sessionCommands));
|
||||
}
|
||||
if (customLayoutChanged) {
|
||||
getInstance()
|
||||
.notifyControllerListener(
|
||||
listener -> listener.onCustomLayoutChanged(getInstance(), resolvedCustomLayout));
|
||||
}
|
||||
if (mediaButtonPreferencesChanged) {
|
||||
getInstance()
|
||||
.notifyControllerListener(
|
||||
listener -> {
|
||||
listener.onCustomLayoutChanged(getInstance(), resolvedMediaButtonPreferences);
|
||||
listener.onMediaButtonPreferencesChanged(
|
||||
getInstance(), resolvedMediaButtonPreferences);
|
||||
});
|
||||
listener ->
|
||||
listener.onMediaButtonPreferencesChanged(
|
||||
getInstance(), resolvedMediaButtonPreferences));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2891,8 +2909,10 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
boolean intersectedPlayerCommandsChanged =
|
||||
!Util.areEqual(intersectedPlayerCommands, prevIntersectedPlayerCommands);
|
||||
boolean mediaButtonPreferencesChanged = false;
|
||||
boolean customLayoutChanged = false;
|
||||
if (intersectedPlayerCommandsChanged) {
|
||||
ImmutableList<CommandButton> oldMediaButtonPreferences = resolvedMediaButtonPreferences;
|
||||
ImmutableList<CommandButton> oldCustomLayout = resolvedCustomLayout;
|
||||
resolvedMediaButtonPreferences =
|
||||
resolveMediaButtonPreferences(
|
||||
mediaButtonPreferencesOriginal,
|
||||
@ -2900,20 +2920,27 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
sessionCommands,
|
||||
intersectedPlayerCommands,
|
||||
sessionExtras);
|
||||
resolvedCustomLayout =
|
||||
resolveCustomLayout(
|
||||
resolvedMediaButtonPreferences, sessionExtras, intersectedPlayerCommands);
|
||||
mediaButtonPreferencesChanged =
|
||||
!resolvedMediaButtonPreferences.equals(oldMediaButtonPreferences);
|
||||
customLayoutChanged = !resolvedCustomLayout.equals(oldCustomLayout);
|
||||
listeners.sendEvent(
|
||||
/* eventFlag= */ Player.EVENT_AVAILABLE_COMMANDS_CHANGED,
|
||||
listener -> listener.onAvailableCommandsChanged(intersectedPlayerCommands));
|
||||
}
|
||||
if (customLayoutChanged) {
|
||||
getInstance()
|
||||
.notifyControllerListener(
|
||||
listener -> listener.onCustomLayoutChanged(getInstance(), resolvedCustomLayout));
|
||||
}
|
||||
if (mediaButtonPreferencesChanged) {
|
||||
getInstance()
|
||||
.notifyControllerListener(
|
||||
listener -> {
|
||||
listener.onCustomLayoutChanged(getInstance(), resolvedMediaButtonPreferences);
|
||||
listener.onMediaButtonPreferencesChanged(
|
||||
getInstance(), resolvedMediaButtonPreferences);
|
||||
});
|
||||
listener ->
|
||||
listener.onMediaButtonPreferencesChanged(
|
||||
getInstance(), resolvedMediaButtonPreferences));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2922,6 +2949,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
return;
|
||||
}
|
||||
ImmutableList<CommandButton> oldMediaButtonPreferences = resolvedMediaButtonPreferences;
|
||||
ImmutableList<CommandButton> oldCustomLayout = resolvedCustomLayout;
|
||||
customLayoutOriginal = ImmutableList.copyOf(layout);
|
||||
resolvedMediaButtonPreferences =
|
||||
resolveMediaButtonPreferences(
|
||||
@ -2930,17 +2958,23 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
sessionCommands,
|
||||
intersectedPlayerCommands,
|
||||
sessionExtras);
|
||||
resolvedCustomLayout =
|
||||
resolveCustomLayout(
|
||||
resolvedMediaButtonPreferences, sessionExtras, intersectedPlayerCommands);
|
||||
boolean mediaButtonPreferencesChanged =
|
||||
!Objects.equals(resolvedMediaButtonPreferences, oldMediaButtonPreferences);
|
||||
!resolvedMediaButtonPreferences.equals(oldMediaButtonPreferences);
|
||||
boolean customLayoutChanged = !resolvedCustomLayout.equals(oldCustomLayout);
|
||||
getInstance()
|
||||
.notifyControllerListener(
|
||||
listener -> {
|
||||
ListenableFuture<SessionResult> future =
|
||||
checkNotNull(
|
||||
listener.onSetCustomLayout(getInstance(), resolvedMediaButtonPreferences),
|
||||
listener.onSetCustomLayout(getInstance(), resolvedCustomLayout),
|
||||
"MediaController.Listener#onSetCustomLayout() must not return null");
|
||||
if (customLayoutChanged) {
|
||||
listener.onCustomLayoutChanged(getInstance(), resolvedCustomLayout);
|
||||
}
|
||||
if (mediaButtonPreferencesChanged) {
|
||||
listener.onCustomLayoutChanged(getInstance(), resolvedMediaButtonPreferences);
|
||||
listener.onMediaButtonPreferencesChanged(
|
||||
getInstance(), resolvedMediaButtonPreferences);
|
||||
}
|
||||
@ -2953,6 +2987,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
return;
|
||||
}
|
||||
ImmutableList<CommandButton> oldMediaButtonPreferences = resolvedMediaButtonPreferences;
|
||||
ImmutableList<CommandButton> oldCustomLayout = resolvedCustomLayout;
|
||||
mediaButtonPreferencesOriginal = ImmutableList.copyOf(mediaButtonPreferences);
|
||||
resolvedMediaButtonPreferences =
|
||||
resolveMediaButtonPreferences(
|
||||
@ -2961,17 +2996,23 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
sessionCommands,
|
||||
intersectedPlayerCommands,
|
||||
sessionExtras);
|
||||
resolvedCustomLayout =
|
||||
resolveCustomLayout(
|
||||
resolvedMediaButtonPreferences, sessionExtras, intersectedPlayerCommands);
|
||||
boolean mediaButtonPreferencesChanged =
|
||||
!Objects.equals(resolvedMediaButtonPreferences, oldMediaButtonPreferences);
|
||||
!resolvedMediaButtonPreferences.equals(oldMediaButtonPreferences);
|
||||
boolean customLayoutChanged = !resolvedCustomLayout.equals(oldCustomLayout);
|
||||
getInstance()
|
||||
.notifyControllerListener(
|
||||
listener -> {
|
||||
ListenableFuture<SessionResult> future =
|
||||
checkNotNull(
|
||||
listener.onSetCustomLayout(getInstance(), resolvedMediaButtonPreferences),
|
||||
listener.onSetCustomLayout(getInstance(), resolvedCustomLayout),
|
||||
"MediaController.Listener#onSetCustomLayout() must not return null");
|
||||
if (customLayoutChanged) {
|
||||
listener.onCustomLayoutChanged(getInstance(), resolvedCustomLayout);
|
||||
}
|
||||
if (mediaButtonPreferencesChanged) {
|
||||
listener.onCustomLayoutChanged(getInstance(), resolvedMediaButtonPreferences);
|
||||
listener.onMediaButtonPreferencesChanged(
|
||||
getInstance(), resolvedMediaButtonPreferences);
|
||||
}
|
||||
@ -2984,6 +3025,7 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
return;
|
||||
}
|
||||
ImmutableList<CommandButton> oldMediaButtonPreferences = resolvedMediaButtonPreferences;
|
||||
ImmutableList<CommandButton> oldCustomLayout = resolvedCustomLayout;
|
||||
sessionExtras = extras;
|
||||
resolvedMediaButtonPreferences =
|
||||
resolveMediaButtonPreferences(
|
||||
@ -2992,14 +3034,20 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
sessionCommands,
|
||||
intersectedPlayerCommands,
|
||||
sessionExtras);
|
||||
resolvedCustomLayout =
|
||||
resolveCustomLayout(
|
||||
resolvedMediaButtonPreferences, sessionExtras, intersectedPlayerCommands);
|
||||
boolean mediaButtonPreferencesChanged =
|
||||
!Objects.equals(resolvedMediaButtonPreferences, oldMediaButtonPreferences);
|
||||
!resolvedMediaButtonPreferences.equals(oldMediaButtonPreferences);
|
||||
boolean customLayoutChanged = !resolvedCustomLayout.equals(oldCustomLayout);
|
||||
getInstance()
|
||||
.notifyControllerListener(
|
||||
listener -> {
|
||||
listener.onExtrasChanged(getInstance(), extras);
|
||||
if (customLayoutChanged) {
|
||||
listener.onCustomLayoutChanged(getInstance(), resolvedCustomLayout);
|
||||
}
|
||||
if (mediaButtonPreferencesChanged) {
|
||||
listener.onCustomLayoutChanged(getInstance(), resolvedMediaButtonPreferences);
|
||||
listener.onMediaButtonPreferencesChanged(
|
||||
getInstance(), resolvedMediaButtonPreferences);
|
||||
}
|
||||
@ -3365,6 +3413,22 @@ import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
resolvedButtons, sessionCommands, playerCommands);
|
||||
}
|
||||
|
||||
private static ImmutableList<CommandButton> resolveCustomLayout(
|
||||
List<CommandButton> mediaButtonPreferences,
|
||||
Bundle sessionExtras,
|
||||
Player.Commands availableCommands) {
|
||||
boolean backSlotAllowed =
|
||||
!sessionExtras.getBoolean(MediaConstants.EXTRAS_KEY_SLOT_RESERVATION_SEEK_TO_PREV)
|
||||
&& !availableCommands.containsAny(
|
||||
Player.COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM, Player.COMMAND_SEEK_TO_PREVIOUS);
|
||||
boolean forwardSlotAllowed =
|
||||
!sessionExtras.getBoolean(MediaConstants.EXTRAS_KEY_SLOT_RESERVATION_SEEK_TO_NEXT)
|
||||
&& !availableCommands.containsAny(
|
||||
Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, Player.COMMAND_SEEK_TO_NEXT);
|
||||
return CommandButton.getCustomLayoutFromMediaButtonPreferences(
|
||||
mediaButtonPreferences, backSlotAllowed, forwardSlotAllowed);
|
||||
}
|
||||
|
||||
private static Commands createIntersectedCommandsEnsuringCommandReleaseAvailable(
|
||||
Commands commandFromSession, Commands commandsFromPlayer) {
|
||||
Commands intersectedCommands = MediaUtils.intersect(commandFromSession, commandsFromPlayer);
|
||||
|
@ -437,6 +437,11 @@ import org.checkerframework.checker.initialization.qual.UnderInitialization;
|
||||
return controllerInfo.mediaButtonPreferences;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ImmutableList<CommandButton> getCustomLayout() {
|
||||
return controllerInfo.mediaButtonPreferences;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Bundle getSessionExtras() {
|
||||
return controllerInfo.sessionExtras;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -335,8 +335,7 @@ public class MediaSessionServiceTest {
|
||||
.containsExactly(
|
||||
button1
|
||||
.copyWithIsEnabled(false)
|
||||
.copyWithSlots(
|
||||
ImmutableIntArray.of(CommandButton.SLOT_FORWARD, CommandButton.SLOT_OVERFLOW)),
|
||||
.copyWithSlots(ImmutableIntArray.of(CommandButton.SLOT_FORWARD)),
|
||||
button2
|
||||
.copyWithIsEnabled(false)
|
||||
.copyWithSlots(ImmutableIntArray.of(CommandButton.SLOT_OVERFLOW)))
|
||||
|
Loading…
x
Reference in New Issue
Block a user