blob: 691eb70a268ae0fddcfe158b36a13681ea243a12 [file] [log] [blame]
/*
* 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 MediaPlayerBase
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<SessionCommand2> 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<SessionCommand2> getCommands() {
return new HashSet<>(mCommands);
}
/**
* @return A new {@link Bundle} instance from the SessionCommandGroup2.
* @hide
*/
@RestrictTo(LIBRARY_GROUP)
public @NonNull Bundle toBundle() {
ArrayList<Bundle> 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<Parcelable> 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;
}
}