/* * Copyright 2018 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package androidx.media; import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; import static androidx.media.SessionCommand2.COMMAND_CODE_CUSTOM; import android.os.Bundle; import android.os.Parcelable; import android.util.Log; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.RestrictTo; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.HashSet; import java.util.List; import java.util.Set; /** * A set of {@link SessionCommand2} which represents a command group. */ public final class SessionCommandGroup2 { private static final String TAG = "SessionCommandGroup2"; private static final String KEY_COMMANDS = "android.media.mediasession2.commandgroup.commands"; // Prefix for all command codes private static final String PREFIX_COMMAND_CODE = "COMMAND_CODE_"; // Prefix for command codes that will be sent directly to the MediaPlayerInterface private static final String PREFIX_COMMAND_CODE_PLAYBACK = "COMMAND_CODE_PLAYBACK_"; // Prefix for command codes that will be sent directly to the MediaPlaylistAgent private static final String PREFIX_COMMAND_CODE_PLAYLIST = "COMMAND_CODE_PLAYLIST_"; // Prefix for command codes that will be sent directly to AudioManager or VolumeProvider. private static final String PREFIX_COMMAND_CODE_VOLUME = "COMMAND_CODE_VOLUME_"; private Set mCommands = new HashSet<>(); /** * Default Constructor. */ public SessionCommandGroup2() { } /** * Creates a new SessionCommandGroup2 with commands copied from another object. * * @param other The SessionCommandGroup2 instance to copy. */ public SessionCommandGroup2(@Nullable SessionCommandGroup2 other) { if (other != null) { mCommands.addAll(other.mCommands); } } /** * Adds a command to this command group. * * @param command A command to add. Shouldn't be {@code null}. */ public void addCommand(@NonNull SessionCommand2 command) { if (command == null) { throw new IllegalArgumentException("command shouldn't be null"); } mCommands.add(command); } /** * Adds a predefined command with given {@code commandCode} to this command group. * * @param commandCode A command code to add. * Shouldn't be {@link SessionCommand2#COMMAND_CODE_CUSTOM}. */ public void addCommand(int commandCode) { if (commandCode == COMMAND_CODE_CUSTOM) { throw new IllegalArgumentException("command shouldn't be null"); } mCommands.add(new SessionCommand2(commandCode)); } /** * Adds all predefined commands to this command group. */ public void addAllPredefinedCommands() { addCommandsWithPrefix(PREFIX_COMMAND_CODE); } void addAllPlaybackCommands() { addCommandsWithPrefix(PREFIX_COMMAND_CODE_PLAYBACK); } void addAllPlaylistCommands() { addCommandsWithPrefix(PREFIX_COMMAND_CODE_PLAYLIST); } void addAllVolumeCommands() { addCommandsWithPrefix(PREFIX_COMMAND_CODE_VOLUME); } private void addCommandsWithPrefix(String prefix) { final Field[] fields = SessionCommand2.class.getFields(); if (fields != null) { for (int i = 0; i < fields.length; i++) { if (fields[i].getName().startsWith(prefix) && !fields[i].getName().equals("COMMAND_CODE_CUSTOM")) { try { mCommands.add(new SessionCommand2(fields[i].getInt(null))); } catch (IllegalAccessException e) { Log.w(TAG, "Unexpected " + fields[i] + " in MediaSession2"); } } } } } /** * Removes a command from this group which matches given {@code command}. * * @param command A command to find. Shouldn't be {@code null}. */ public void removeCommand(@NonNull SessionCommand2 command) { if (command == null) { throw new IllegalArgumentException("command shouldn't be null"); } mCommands.remove(command); } /** * Removes a command from this group which matches given {@code commandCode}. * * @param commandCode A command code to find. * Shouldn't be {@link SessionCommand2#COMMAND_CODE_CUSTOM}. */ public void removeCommand(int commandCode) { if (commandCode == COMMAND_CODE_CUSTOM) { throw new IllegalArgumentException("commandCode shouldn't be COMMAND_CODE_CUSTOM"); } mCommands.remove(new SessionCommand2(commandCode)); } /** * Checks whether this command group has a command that matches given {@code command}. * * @param command A command to find. Shouldn't be {@code null}. */ public boolean hasCommand(@NonNull SessionCommand2 command) { if (command == null) { throw new IllegalArgumentException("command shouldn't be null"); } return mCommands.contains(command); } /** * Checks whether this command group has a command that matches given {@code commandCode}. * * @param commandCode A command code to find. * Shouldn't be {@link SessionCommand2#COMMAND_CODE_CUSTOM}. */ public boolean hasCommand(int commandCode) { if (commandCode == COMMAND_CODE_CUSTOM) { throw new IllegalArgumentException("Use hasCommand(Command) for custom command"); } for (SessionCommand2 command : mCommands) { if (command.getCommandCode() == commandCode) { return true; } } return false; } /** * Gets all commands of this command group. */ public @NonNull Set getCommands() { return new HashSet<>(mCommands); } /** * @return A new {@link Bundle} instance from the SessionCommandGroup2. * @hide */ @RestrictTo(LIBRARY_GROUP) public @NonNull Bundle toBundle() { ArrayList list = new ArrayList<>(); for (SessionCommand2 command : mCommands) { list.add(command.toBundle()); } Bundle bundle = new Bundle(); bundle.putParcelableArrayList(KEY_COMMANDS, list); return bundle; } /** * @return A new {@link SessionCommandGroup2} instance from the bundle. * @hide */ @RestrictTo(LIBRARY_GROUP) public static @Nullable SessionCommandGroup2 fromBundle(Bundle commands) { if (commands == null) { return null; } List list = commands.getParcelableArrayList(KEY_COMMANDS); if (list == null) { return null; } SessionCommandGroup2 commandGroup = new SessionCommandGroup2(); for (int i = 0; i < list.size(); i++) { Parcelable parcelable = list.get(i); if (!(parcelable instanceof Bundle)) { continue; } Bundle commandBundle = (Bundle) parcelable; SessionCommand2 command = SessionCommand2.fromBundle(commandBundle); if (command != null) { commandGroup.addCommand(command); } } return commandGroup; } }