Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d5b878d0 authored by Jaewan Kim's avatar Jaewan Kim
Browse files

MediaSession2: Pull out Command/CommandGroup from the MediaSession2

Bug: 74648408
Test: Build
Change-Id: Ie688f4ccc2e26ed99e9f6d931d0fdcf87574cb54
parent 076d7da0
Loading
Loading
Loading
Loading
+29 −30
Original line number Diff line number Diff line
@@ -16,20 +16,20 @@

package com.android.media;

import static android.media.MediaSession2.COMMAND_CODE_PLAYBACK_SET_VOLUME;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_ADD_ITEM;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_REMOVE_ITEM;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_REPLACE_ITEM;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_SET_LIST;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_SET_LIST_METADATA;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE;
import static android.media.MediaSession2.COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE;
import static android.media.MediaSession2.COMMAND_CODE_SESSION_PLAY_FROM_MEDIA_ID;
import static android.media.MediaSession2.COMMAND_CODE_SESSION_PLAY_FROM_SEARCH;
import static android.media.MediaSession2.COMMAND_CODE_SESSION_PLAY_FROM_URI;
import static android.media.MediaSession2.COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID;
import static android.media.MediaSession2.COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH;
import static android.media.MediaSession2.COMMAND_CODE_SESSION_PREPARE_FROM_URI;
import static android.media.SessionCommand2.COMMAND_CODE_SET_VOLUME;
import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_ADD_ITEM;
import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_REMOVE_ITEM;
import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_REPLACE_ITEM;
import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_LIST;
import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_LIST_METADATA;
import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE;
import static android.media.SessionCommand2.COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE;
import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_MEDIA_ID;
import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_SEARCH;
import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PLAY_FROM_URI;
import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID;
import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH;
import static android.media.SessionCommand2.COMMAND_CODE_SESSION_PREPARE_FROM_URI;

import android.app.PendingIntent;
import android.content.ComponentName;
@@ -44,10 +44,9 @@ import android.media.MediaItem2;
import android.media.MediaMetadata2;
import android.media.MediaPlaylistAgent.RepeatMode;
import android.media.MediaPlaylistAgent.ShuffleMode;
import android.media.MediaSession2;
import android.media.MediaSession2.Command;
import android.media.SessionCommand2;
import android.media.MediaSession2.CommandButton;
import android.media.MediaSession2.CommandGroup;
import android.media.SessionCommandGroup2;
import android.media.MediaSessionService2;
import android.media.Rating2;
import android.media.SessionToken2;
@@ -108,7 +107,7 @@ public class MediaController2Impl implements MediaController2Provider {
    @GuardedBy("mLock")
    private PendingIntent mSessionActivity;
    @GuardedBy("mLock")
    private CommandGroup mAllowedCommands;
    private SessionCommandGroup2 mAllowedCommands;

    // Assignment should be used with the lock hold, but should be used without a lock to prevent
    // potential deadlock.
@@ -297,7 +296,7 @@ public class MediaController2Impl implements MediaController2Provider {
    }

    // Returns session binder if the controller can send the command.
    IMediaSession2 getSessionBinderIfAble(Command command) {
    IMediaSession2 getSessionBinderIfAble(SessionCommand2 command) {
        synchronized (mLock) {
            if (!mAllowedCommands.hasCommand(command)) {
                Log.w(TAG, "Controller isn't allowed to call command, command=" + command);
@@ -326,17 +325,17 @@ public class MediaController2Impl implements MediaController2Provider {

    @Override
    public void play_impl() {
        sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_PLAY);
        sendTransportControlCommand(SessionCommand2.COMMAND_CODE_PLAYBACK_PLAY);
    }

    @Override
    public void pause_impl() {
        sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_PAUSE);
        sendTransportControlCommand(SessionCommand2.COMMAND_CODE_PLAYBACK_PAUSE);
    }

    @Override
    public void stop_impl() {
        sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_STOP);
        sendTransportControlCommand(SessionCommand2.COMMAND_CODE_PLAYBACK_STOP);
    }

    @Override
@@ -409,7 +408,7 @@ public class MediaController2Impl implements MediaController2Provider {
    @Override
    public void setVolumeTo_impl(int value, int flags) {
        // TODO(hdmoon): sanity check
        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PLAYBACK_SET_VOLUME);
        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_SET_VOLUME);
        if (binder != null) {
            try {
                binder.setVolumeTo(mControllerStub, value, flags);
@@ -424,7 +423,7 @@ public class MediaController2Impl implements MediaController2Provider {
    @Override
    public void adjustVolume_impl(int direction, int flags) {
        // TODO(hdmoon): sanity check
        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_PLAYBACK_SET_VOLUME);
        final IMediaSession2 binder = getSessionBinderIfAble(COMMAND_CODE_SET_VOLUME);
        if (binder != null) {
            try {
                binder.adjustVolume(mControllerStub, direction, flags);
@@ -563,7 +562,7 @@ public class MediaController2Impl implements MediaController2Provider {
    }

    @Override
    public void sendCustomCommand_impl(Command command, Bundle args, ResultReceiver cb) {
    public void sendCustomCommand_impl(SessionCommand2 command, Bundle args, ResultReceiver cb) {
        if (command == null) {
            throw new IllegalArgumentException("command shouldn't be null");
        }
@@ -633,7 +632,7 @@ public class MediaController2Impl implements MediaController2Provider {

    @Override
    public void prepare_impl() {
        sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_PREPARE);
        sendTransportControlCommand(SessionCommand2.COMMAND_CODE_PLAYBACK_PREPARE);
    }

    @Override
@@ -655,7 +654,7 @@ public class MediaController2Impl implements MediaController2Provider {
        }
        Bundle args = new Bundle();
        args.putLong(MediaSession2Stub.ARGUMENT_KEY_POSITION, pos);
        sendTransportControlCommand(MediaSession2.COMMAND_CODE_PLAYBACK_SEEK_TO, args);
        sendTransportControlCommand(SessionCommand2.COMMAND_CODE_PLAYBACK_SEEK_TO, args);
    }

    @Override
@@ -919,7 +918,7 @@ public class MediaController2Impl implements MediaController2Provider {

    // Should be used without a lock to prevent potential deadlock.
    void onConnectedNotLocked(IMediaSession2 sessionBinder,
            final CommandGroup allowedCommands,
            final SessionCommandGroup2 allowedCommands,
            final int playerState,
            final long positionEventTimeMs,
            final long positionMs,
@@ -991,7 +990,7 @@ public class MediaController2Impl implements MediaController2Provider {
        }
    }

    void onCustomCommand(final Command command, final Bundle args,
    void onCustomCommand(final SessionCommand2 command, final Bundle args,
            final ResultReceiver receiver) {
        if (DEBUG) {
            Log.d(TAG, "onCustomCommand cmd=" + command);
@@ -1002,7 +1001,7 @@ public class MediaController2Impl implements MediaController2Provider {
        });
    }

    void onAllowedCommandsChanged(final CommandGroup commands) {
    void onAllowedCommandsChanged(final SessionCommandGroup2 commands) {
        mCallbackExecutor.execute(() -> {
            mCallback.onAllowedCommandsChanged(mInstance, commands);
        });
+5 −5
Original line number Diff line number Diff line
@@ -21,9 +21,9 @@ import android.content.Context;
import android.media.MediaController2;
import android.media.MediaItem2;
import android.media.MediaMetadata2;
import android.media.MediaSession2.Command;
import android.media.SessionCommand2;
import android.media.MediaSession2.CommandButton;
import android.media.MediaSession2.CommandGroup;
import android.media.SessionCommandGroup2;
import android.os.Bundle;
import android.os.ResultReceiver;
import android.text.TextUtils;
@@ -245,7 +245,7 @@ public class MediaController2Stub extends IMediaController2.Stub {
            }
        }
        controller.onConnectedNotLocked(sessionBinder,
                CommandGroup.fromBundle(commandGroup),
                SessionCommandGroup2.fromBundle(commandGroup),
                playerState, positionEventTimeMs, positionMs, playbackSpeed, bufferedPositionMs,
                PlaybackInfoImpl.fromBundle(playbackInfo), repeatMode, shuffleMode,
                itemList, sessionActivity);
@@ -303,7 +303,7 @@ public class MediaController2Stub extends IMediaController2.Stub {
            // TODO(jaewan): Revisit here. Could be a bug
            return;
        }
        CommandGroup commands = CommandGroup.fromBundle(commandsBundle);
        SessionCommandGroup2 commands = SessionCommandGroup2.fromBundle(commandsBundle);
        if (commands == null) {
            Log.w(TAG, "onAllowedCommandsChanged(): Ignoring null commands");
            return;
@@ -320,7 +320,7 @@ public class MediaController2Stub extends IMediaController2.Stub {
            Log.w(TAG, "Don't fail silently here. Highly likely a bug");
            return;
        }
        Command command = Command.fromBundle(commandBundle);
        SessionCommand2 command = SessionCommand2.fromBundle(commandBundle);
        if (command == null) {
            Log.w(TAG, "onCustomCommand(): Ignoring null command");
            return;
+37 −35
Original line number Diff line number Diff line
@@ -16,7 +16,7 @@

package com.android.media;

import static android.media.MediaSession2.COMMAND_CODE_CUSTOM;
import static android.media.SessionCommand2.COMMAND_CODE_CUSTOM;
import static android.media.SessionToken2.TYPE_LIBRARY_SERVICE;
import static android.media.SessionToken2.TYPE_SESSION;
import static android.media.SessionToken2.TYPE_SESSION_SERVICE;
@@ -44,9 +44,9 @@ import android.media.MediaPlaylistAgent;
import android.media.MediaPlaylistAgent.PlaylistEventCallback;
import android.media.MediaSession2;
import android.media.MediaSession2.Builder;
import android.media.MediaSession2.Command;
import android.media.SessionCommand2;
import android.media.MediaSession2.CommandButton;
import android.media.MediaSession2.CommandGroup;
import android.media.SessionCommandGroup2;
import android.media.MediaSession2.ControllerInfo;
import android.media.MediaSession2.OnDataSourceMissingHelper;
import android.media.MediaSession2.SessionCallback;
@@ -444,7 +444,7 @@ public class MediaSession2Impl implements MediaSession2Provider {

    @Override
    public void setAllowedCommands_impl(@NonNull ControllerInfo controller,
            @NonNull CommandGroup commands) {
            @NonNull SessionCommandGroup2 commands) {
        if (controller == null) {
            throw new IllegalArgumentException("controller shouldn't be null");
        }
@@ -455,8 +455,8 @@ public class MediaSession2Impl implements MediaSession2Provider {
    }

    @Override
    public void sendCustomCommand_impl(@NonNull ControllerInfo controller, @NonNull Command command,
            Bundle args, ResultReceiver receiver) {
    public void sendCustomCommand_impl(@NonNull ControllerInfo controller,
            @NonNull SessionCommand2 command, Bundle args, ResultReceiver receiver) {
        if (controller == null) {
            throw new IllegalArgumentException("controller shouldn't be null");
        }
@@ -467,7 +467,7 @@ public class MediaSession2Impl implements MediaSession2Provider {
    }

    @Override
    public void sendCustomCommand_impl(@NonNull Command command, Bundle args) {
    public void sendCustomCommand_impl(@NonNull SessionCommand2 command, Bundle args) {
        if (command == null) {
            throw new IllegalArgumentException("command shouldn't be null");
        }
@@ -980,20 +980,21 @@ public class MediaSession2Impl implements MediaSession2Provider {
        private static final String KEY_COMMAND_EXTRAS
                = "android.media.media_session2.command.extras";

        private final Command mInstance;
        private final SessionCommand2 mInstance;
        private final int mCommandCode;
        // Nonnull if it's custom command
        private final String mCustomCommand;
        private final Bundle mExtras;

        public CommandImpl(Command instance, int commandCode) {
        public CommandImpl(SessionCommand2 instance, int commandCode) {
            mInstance = instance;
            mCommandCode = commandCode;
            mCustomCommand = null;
            mExtras = null;
        }

        public CommandImpl(Command instance, @NonNull String action, @Nullable Bundle extras) {
        public CommandImpl(SessionCommand2 instance, @NonNull String action,
                @Nullable Bundle extras) {
            if (action == null) {
                throw new IllegalArgumentException("action shouldn't be null");
            }
@@ -1033,19 +1034,19 @@ public class MediaSession2Impl implements MediaSession2Provider {
        /**
         * @return a new Command instance from the Bundle
         */
        public static Command fromBundle_impl(@NonNull Bundle command) {
        public static SessionCommand2 fromBundle_impl(@NonNull Bundle command) {
            if (command == null) {
                throw new IllegalArgumentException("command shouldn't be null");
            }
            int code = command.getInt(KEY_COMMAND_CODE);
            if (code != COMMAND_CODE_CUSTOM) {
                return new Command(code);
                return new SessionCommand2(code);
            } else {
                String customCommand = command.getString(KEY_COMMAND_CUSTOM_COMMAND);
                if (customCommand == null) {
                    return null;
                }
                return new Command(customCommand, command.getBundle(KEY_COMMAND_EXTRAS));
                return new SessionCommand2(customCommand, command.getBundle(KEY_COMMAND_EXTRAS));
            }
        }

@@ -1069,7 +1070,7 @@ public class MediaSession2Impl implements MediaSession2Provider {
    }

    /**
     * Represent set of {@link Command}.
     * Represent set of {@link SessionCommand2}.
     */
    public static class CommandGroupImpl implements CommandGroupProvider {
        private static final String KEY_COMMANDS =
@@ -1084,10 +1085,10 @@ public class MediaSession2Impl implements MediaSession2Provider {
        // Prefix for command codes that will be sent directly to the MediaPlaylistAgent
        private static final String PREFIX_COMMAND_CODE_PLAYLIST = "COMMAND_CODE_PLAYLIST_";

        private Set<Command> mCommands = new HashSet<>();
        private final CommandGroup mInstance;
        private Set<SessionCommand2> mCommands = new HashSet<>();
        private final SessionCommandGroup2 mInstance;

        public CommandGroupImpl(CommandGroup instance, Object other) {
        public CommandGroupImpl(SessionCommandGroup2 instance, Object other) {
            mInstance = instance;
            if (other != null && other instanceof CommandGroupImpl) {
                mCommands.addAll(((CommandGroupImpl) other).mCommands);
@@ -1095,11 +1096,11 @@ public class MediaSession2Impl implements MediaSession2Provider {
        }

        public CommandGroupImpl() {
            mInstance = new CommandGroup(this);
            mInstance = new SessionCommandGroup2(this);
        }

        @Override
        public void addCommand_impl(@NonNull Command command) {
        public void addCommand_impl(@NonNull SessionCommand2 command) {
            if (command == null) {
                throw new IllegalArgumentException("command shouldn't be null");
            }
@@ -1126,7 +1127,7 @@ public class MediaSession2Impl implements MediaSession2Provider {
                for (int i = 0; i < fields.length; i++) {
                    if (fields[i].getName().startsWith(prefix)) {
                        try {
                            mCommands.add(new Command(fields[i].getInt(null)));
                            mCommands.add(new SessionCommand2(fields[i].getInt(null)));
                        } catch (IllegalAccessException e) {
                            Log.w(TAG, "Unexpected " + fields[i] + " in MediaSession2");
                        }
@@ -1136,7 +1137,7 @@ public class MediaSession2Impl implements MediaSession2Provider {
        }

        @Override
        public void removeCommand_impl(@NonNull Command command) {
        public void removeCommand_impl(@NonNull SessionCommand2 command) {
            if (command == null) {
                throw new IllegalArgumentException("command shouldn't be null");
            }
@@ -1144,7 +1145,7 @@ public class MediaSession2Impl implements MediaSession2Provider {
        }

        @Override
        public boolean hasCommand_impl(@NonNull Command command) {
        public boolean hasCommand_impl(@NonNull SessionCommand2 command) {
            if (command == null) {
                throw new IllegalArgumentException("command shouldn't be null");
            }
@@ -1156,7 +1157,7 @@ public class MediaSession2Impl implements MediaSession2Provider {
            if (code == COMMAND_CODE_CUSTOM) {
                throw new IllegalArgumentException("Use hasCommand(Command) for custom command");
            }
            for (Command command : mCommands) {
            for (SessionCommand2 command : mCommands) {
                if (command.getCommandCode() == code) {
                    return true;
                }
@@ -1165,11 +1166,11 @@ public class MediaSession2Impl implements MediaSession2Provider {
        }

        @Override
        public Set<Command> getCommands_impl() {
        public Set<SessionCommand2> getCommands_impl() {
            return getCommands();
        }

        public Set<Command> getCommands() {
        public Set<SessionCommand2> getCommands() {
            return Collections.unmodifiableSet(mCommands);
        }

@@ -1180,7 +1181,7 @@ public class MediaSession2Impl implements MediaSession2Provider {
        @Override
        public Bundle toBundle_impl() {
            ArrayList<Bundle> list = new ArrayList<>();
            for (Command command : mCommands) {
            for (SessionCommand2 command : mCommands) {
                list.add(command.toBundle());
            }
            Bundle bundle = new Bundle();
@@ -1192,7 +1193,7 @@ public class MediaSession2Impl implements MediaSession2Provider {
         * @return new instance of CommandGroup from the bundle
         * @hide
         */
        public static @Nullable CommandGroup fromBundle_impl(Bundle commands) {
        public static @Nullable SessionCommandGroup2 fromBundle_impl(Bundle commands) {
            if (commands == null) {
                return null;
            }
@@ -1200,14 +1201,14 @@ public class MediaSession2Impl implements MediaSession2Provider {
            if (list == null) {
                return null;
            }
            CommandGroup commandGroup = new CommandGroup();
            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;
                Command command = Command.fromBundle(commandBundle);
                SessionCommand2 command = SessionCommand2.fromBundle(commandBundle);
                if (command != null) {
                    commandGroup.addCommand(command);
                }
@@ -1322,13 +1323,13 @@ public class MediaSession2Impl implements MediaSession2Provider {
                = "android.media.media_session2.command_button.enabled";

        private final CommandButton mInstance;
        private Command mCommand;
        private SessionCommand2 mCommand;
        private int mIconResId;
        private String mDisplayName;
        private Bundle mExtras;
        private boolean mEnabled;

        public CommandButtonImpl(@Nullable Command command, int iconResId,
        public CommandButtonImpl(@Nullable SessionCommand2 command, int iconResId,
                @Nullable String displayName, Bundle extras, boolean enabled) {
            mCommand = command;
            mIconResId = iconResId;
@@ -1339,7 +1340,8 @@ public class MediaSession2Impl implements MediaSession2Provider {
        }

        @Override
        public @Nullable Command getCommand_impl() {
        public @Nullable
        SessionCommand2 getCommand_impl() {
            return mCommand;
        }

@@ -1378,7 +1380,7 @@ public class MediaSession2Impl implements MediaSession2Provider {
                return null;
            }
            CommandButton.Builder builder = new CommandButton.Builder();
            builder.setCommand(Command.fromBundle(bundle.getBundle(KEY_COMMAND)));
            builder.setCommand(SessionCommand2.fromBundle(bundle.getBundle(KEY_COMMAND)));
            builder.setIconResId(bundle.getInt(KEY_ICON_RES_ID, 0));
            builder.setDisplayName(bundle.getString(KEY_DISPLAY_NAME));
            builder.setExtras(bundle.getBundle(KEY_EXTRAS));
@@ -1396,7 +1398,7 @@ public class MediaSession2Impl implements MediaSession2Provider {
         */
        public static class BuilderImpl implements CommandButtonProvider.BuilderProvider {
            private final CommandButton.Builder mInstance;
            private Command mCommand;
            private SessionCommand2 mCommand;
            private int mIconResId;
            private String mDisplayName;
            private Bundle mExtras;
@@ -1408,7 +1410,7 @@ public class MediaSession2Impl implements MediaSession2Provider {
            }

            @Override
            public CommandButton.Builder setCommand_impl(Command command) {
            public CommandButton.Builder setCommand_impl(SessionCommand2 command) {
                mCommand = command;
                return mInstance;
            }
+133 −119

File changed.

Preview size limit exceeded, changes collapsed.

+6 −6
Original line number Diff line number Diff line
@@ -31,8 +31,8 @@ import android.media.MediaLibraryService2.MediaLibrarySession.MediaLibrarySessio
import android.media.MediaMetadata2;
import android.media.MediaPlaylistAgent;
import android.media.MediaSession2;
import android.media.MediaSession2.Command;
import android.media.MediaSession2.CommandGroup;
import android.media.SessionCommand2;
import android.media.SessionCommandGroup2;
import android.media.MediaSession2.ControllerInfo;
import android.media.MediaSession2.SessionCallback;
import android.media.MediaSessionService2;
@@ -105,7 +105,7 @@ public final class ApiFactory implements StaticProvider {

    @Override
    public MediaSession2Provider.CommandProvider createMediaSession2Command(
            Command instance, int commandCode, String action, Bundle extra) {
            SessionCommand2 instance, int commandCode, String action, Bundle extra) {
        if (action == null && extra == null) {
            return new MediaSession2Impl.CommandImpl(instance, commandCode);
        }
@@ -113,19 +113,19 @@ public final class ApiFactory implements StaticProvider {
    }

    @Override
    public Command fromBundle_MediaSession2Command(Bundle command) {
    public SessionCommand2 fromBundle_MediaSession2Command(Bundle command) {
        return MediaSession2Impl.CommandImpl.fromBundle_impl(command);
    }

    @Override
    public MediaSession2Provider.CommandGroupProvider createMediaSession2CommandGroup(
            CommandGroup instance, CommandGroup other) {
            SessionCommandGroup2 instance, SessionCommandGroup2 other) {
        return new MediaSession2Impl.CommandGroupImpl(instance,
                (other == null) ? null : other.getProvider());
    }

    @Override
    public CommandGroup fromBundle_MediaSession2CommandGroup(Bundle commands) {
    public SessionCommandGroup2 fromBundle_MediaSession2CommandGroup(Bundle commands) {
        return MediaSession2Impl.CommandGroupImpl.fromBundle_impl(commands);
    }