|
19 | 19 | import static androidx.media.utils.MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_SUPPORTED_FLAGS;
|
20 | 20 | import static androidx.media3.common.Player.COMMAND_ADJUST_DEVICE_VOLUME;
|
21 | 21 | import static androidx.media3.common.Player.COMMAND_CHANGE_MEDIA_ITEMS;
|
| 22 | +import static androidx.media3.common.Player.COMMAND_GET_AUDIO_ATTRIBUTES; |
22 | 23 | import static androidx.media3.common.Player.COMMAND_GET_CURRENT_MEDIA_ITEM;
|
23 | 24 | import static androidx.media3.common.Player.COMMAND_GET_DEVICE_VOLUME;
|
24 | 25 | import static androidx.media3.common.Player.COMMAND_GET_MEDIA_ITEMS_METADATA;
|
25 | 26 | import static androidx.media3.common.Player.COMMAND_GET_TIMELINE;
|
26 | 27 | import static androidx.media3.common.Player.COMMAND_PLAY_PAUSE;
|
27 | 28 | import static androidx.media3.common.Player.COMMAND_PREPARE;
|
| 29 | +import static androidx.media3.common.Player.COMMAND_SEEK_BACK; |
| 30 | +import static androidx.media3.common.Player.COMMAND_SEEK_FORWARD; |
28 | 31 | import static androidx.media3.common.Player.COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM;
|
| 32 | +import static androidx.media3.common.Player.COMMAND_SEEK_TO_DEFAULT_POSITION; |
29 | 33 | import static androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT;
|
30 | 34 | import static androidx.media3.common.Player.COMMAND_SEEK_TO_NEXT_MEDIA_ITEM;
|
31 | 35 | import static androidx.media3.common.Player.COMMAND_SEEK_TO_PREVIOUS;
|
|
65 | 69 | import androidx.annotation.Nullable;
|
66 | 70 | import androidx.media.AudioAttributesCompat;
|
67 | 71 | import androidx.media.MediaBrowserServiceCompat.BrowserRoot;
|
| 72 | +import androidx.media.VolumeProviderCompat; |
68 | 73 | import androidx.media3.common.AdPlaybackState;
|
69 | 74 | import androidx.media3.common.AudioAttributes;
|
70 | 75 | import androidx.media3.common.C;
|
@@ -1070,42 +1075,103 @@ public static List removeNullElements(List<@NullableType T> list) {
|
1070 | 1075 | }
|
1071 | 1076 |
|
1072 | 1077 | /**
|
1073 |
| - * Converts {@link MediaControllerCompat#getFlags() session flags} and {@link |
1074 |
| - * MediaControllerCompat#isSessionReady whether session is ready} to {@link Player.Commands}. |
| 1078 | + * Converts {@link PlaybackStateCompat}, {@link |
| 1079 | + * MediaControllerCompat.PlaybackInfo#getVolumeControl() volume control type}, {@link |
| 1080 | + * MediaControllerCompat#getFlags() session flags} and {@link MediaControllerCompat#isSessionReady |
| 1081 | + * whether the session is ready} to {@link Player.Commands}. |
1075 | 1082 | *
|
1076 |
| - * @param sessionFlags The session flag. |
| 1083 | + * @param playbackStateCompat The {@link PlaybackStateCompat}. |
| 1084 | + * @param volumeControlType The {@link MediaControllerCompat.PlaybackInfo#getVolumeControl() |
| 1085 | + * volume control type}. |
| 1086 | + * @param sessionFlags The session flags. |
1077 | 1087 | * @param isSessionReady Whether the session compat is ready.
|
1078 | 1088 | * @return The converted player commands.
|
1079 | 1089 | */
|
1080 |
| - public static Player.Commands convertToPlayerCommands(long sessionFlags, boolean isSessionReady) { |
| 1090 | + public static Player.Commands convertToPlayerCommands( |
| 1091 | + @Nullable PlaybackStateCompat playbackStateCompat, |
| 1092 | + int volumeControlType, |
| 1093 | + long sessionFlags, |
| 1094 | + boolean isSessionReady) { |
1081 | 1095 | Commands.Builder playerCommandsBuilder = new Commands.Builder();
|
| 1096 | + long actions = playbackStateCompat == null ? 0 : playbackStateCompat.getActions(); |
| 1097 | + if ((hasAction(actions, PlaybackStateCompat.ACTION_PLAY) |
| 1098 | + && hasAction(actions, PlaybackStateCompat.ACTION_PAUSE)) |
| 1099 | + || hasAction(actions, PlaybackStateCompat.ACTION_PLAY_PAUSE)) { |
| 1100 | + playerCommandsBuilder.add(COMMAND_PLAY_PAUSE); |
| 1101 | + } |
| 1102 | + if (hasAction(actions, PlaybackStateCompat.ACTION_PREPARE)) { |
| 1103 | + playerCommandsBuilder.add(COMMAND_PREPARE); |
| 1104 | + } |
| 1105 | + if ((hasAction(actions, PlaybackStateCompat.ACTION_PREPARE_FROM_MEDIA_ID) |
| 1106 | + && hasAction(actions, PlaybackStateCompat.ACTION_PLAY_FROM_MEDIA_ID)) |
| 1107 | + || (hasAction(actions, PlaybackStateCompat.ACTION_PREPARE_FROM_SEARCH) |
| 1108 | + && hasAction(actions, PlaybackStateCompat.ACTION_PLAY_FROM_SEARCH)) |
| 1109 | + || (hasAction(actions, PlaybackStateCompat.ACTION_PREPARE_FROM_URI) |
| 1110 | + && hasAction(actions, PlaybackStateCompat.ACTION_PLAY_FROM_URI))) { |
| 1111 | + // Require both PREPARE and PLAY actions as we have no logic to handle having just one action. |
| 1112 | + playerCommandsBuilder.addAll(COMMAND_SET_MEDIA_ITEM, COMMAND_PREPARE); |
| 1113 | + } |
| 1114 | + if (hasAction(actions, PlaybackStateCompat.ACTION_REWIND)) { |
| 1115 | + playerCommandsBuilder.add(COMMAND_SEEK_BACK); |
| 1116 | + } |
| 1117 | + if (hasAction(actions, PlaybackStateCompat.ACTION_FAST_FORWARD)) { |
| 1118 | + playerCommandsBuilder.add(COMMAND_SEEK_FORWARD); |
| 1119 | + } |
| 1120 | + if (hasAction(actions, PlaybackStateCompat.ACTION_SEEK_TO)) { |
| 1121 | + playerCommandsBuilder.addAll( |
| 1122 | + COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, COMMAND_SEEK_TO_DEFAULT_POSITION); |
| 1123 | + } |
| 1124 | + if (hasAction(actions, PlaybackStateCompat.ACTION_SKIP_TO_NEXT)) { |
| 1125 | + playerCommandsBuilder.addAll(COMMAND_SEEK_TO_NEXT, COMMAND_SEEK_TO_NEXT_MEDIA_ITEM); |
| 1126 | + } |
| 1127 | + if (hasAction(actions, PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS)) { |
| 1128 | + playerCommandsBuilder.addAll(COMMAND_SEEK_TO_PREVIOUS, COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM); |
| 1129 | + } |
| 1130 | + if (hasAction(actions, PlaybackStateCompat.ACTION_SET_PLAYBACK_SPEED)) { |
| 1131 | + playerCommandsBuilder.add(COMMAND_SET_SPEED_AND_PITCH); |
| 1132 | + } |
| 1133 | + if (hasAction(actions, PlaybackStateCompat.ACTION_STOP)) { |
| 1134 | + playerCommandsBuilder.add(COMMAND_STOP); |
| 1135 | + } |
| 1136 | + if (volumeControlType == VolumeProviderCompat.VOLUME_CONTROL_RELATIVE) { |
| 1137 | + playerCommandsBuilder.add(COMMAND_ADJUST_DEVICE_VOLUME); |
| 1138 | + } else if (volumeControlType == VolumeProviderCompat.VOLUME_CONTROL_ABSOLUTE) { |
| 1139 | + playerCommandsBuilder.addAll(COMMAND_ADJUST_DEVICE_VOLUME, COMMAND_SET_DEVICE_VOLUME); |
| 1140 | + } |
1082 | 1141 | playerCommandsBuilder.addAll(
|
1083 |
| - COMMAND_PLAY_PAUSE, |
1084 |
| - COMMAND_PREPARE, |
1085 |
| - COMMAND_STOP, |
1086 |
| - COMMAND_SEEK_IN_CURRENT_MEDIA_ITEM, |
1087 |
| - COMMAND_SET_SPEED_AND_PITCH, |
1088 | 1142 | COMMAND_GET_DEVICE_VOLUME,
|
1089 |
| - COMMAND_SET_DEVICE_VOLUME, |
1090 |
| - COMMAND_ADJUST_DEVICE_VOLUME, |
1091 | 1143 | COMMAND_GET_TIMELINE,
|
1092 |
| - COMMAND_SEEK_TO_PREVIOUS, |
1093 |
| - COMMAND_SEEK_TO_PREVIOUS_MEDIA_ITEM, |
1094 |
| - COMMAND_SEEK_TO_NEXT, |
1095 |
| - COMMAND_SEEK_TO_NEXT_MEDIA_ITEM, |
1096 | 1144 | COMMAND_GET_MEDIA_ITEMS_METADATA,
|
1097 | 1145 | COMMAND_GET_CURRENT_MEDIA_ITEM,
|
1098 |
| - COMMAND_SET_MEDIA_ITEM); |
1099 |
| - boolean includePlaylistCommands = (sessionFlags & FLAG_HANDLES_QUEUE_COMMANDS) != 0; |
1100 |
| - if (includePlaylistCommands) { |
| 1146 | + COMMAND_GET_AUDIO_ATTRIBUTES); |
| 1147 | + if ((sessionFlags & FLAG_HANDLES_QUEUE_COMMANDS) != 0) { |
1101 | 1148 | playerCommandsBuilder.add(COMMAND_CHANGE_MEDIA_ITEMS);
|
| 1149 | + if (hasAction(actions, PlaybackStateCompat.ACTION_SKIP_TO_QUEUE_ITEM)) { |
| 1150 | + playerCommandsBuilder.add(Player.COMMAND_SEEK_TO_MEDIA_ITEM); |
| 1151 | + } |
1102 | 1152 | }
|
1103 | 1153 | if (isSessionReady) {
|
1104 |
| - playerCommandsBuilder.addAll(COMMAND_SET_SHUFFLE_MODE, COMMAND_SET_REPEAT_MODE); |
| 1154 | + if (hasAction(actions, PlaybackStateCompat.ACTION_SET_REPEAT_MODE)) { |
| 1155 | + playerCommandsBuilder.add(COMMAND_SET_REPEAT_MODE); |
| 1156 | + } |
| 1157 | + if (hasAction(actions, PlaybackStateCompat.ACTION_SET_SHUFFLE_MODE)) { |
| 1158 | + playerCommandsBuilder.add(COMMAND_SET_SHUFFLE_MODE); |
| 1159 | + } |
1105 | 1160 | }
|
1106 | 1161 | return playerCommandsBuilder.build();
|
1107 | 1162 | }
|
1108 | 1163 |
|
| 1164 | + /** |
| 1165 | + * Checks if the set of actions contains the specified action. |
| 1166 | + * |
| 1167 | + * @param actions A bit set of actions. |
| 1168 | + * @param action The action to check. |
| 1169 | + * @return Whether the action is contained in the set. |
| 1170 | + */ |
| 1171 | + private static boolean hasAction(long actions, @PlaybackStateCompat.Actions long action) { |
| 1172 | + return (actions & action) != 0; |
| 1173 | + } |
| 1174 | + |
1109 | 1175 | /**
|
1110 | 1176 | * Converts {@link PlaybackStateCompat} to {@link SessionCommands}.
|
1111 | 1177 | *
|
|
0 commit comments