From 2a981a0cb5f5c2833385c8311ec1d75172694856 Mon Sep 17 00:00:00 2001 From: Sungsoo Lim Date: Mon, 29 Jan 2018 16:15:11 +0900 Subject: [PATCH] Make MediaSession2.Command updatable Bug: 72619281 Test: build Change-Id: I2b86b68f2d4840da76c992aac056512ac0cb2e20 --- media/java/android/media/MediaLibraryService2.java | 5 + media/java/android/media/MediaSession2.java | 113 ++++++++------------- .../media/update/MediaSession2Provider.java | 11 ++ .../java/android/media/update/StaticProvider.java | 9 ++ 4 files changed, 70 insertions(+), 68 deletions(-) diff --git a/media/java/android/media/MediaLibraryService2.java b/media/java/android/media/MediaLibraryService2.java index 94ada135964b..79b105fb9706 100644 --- a/media/java/android/media/MediaLibraryService2.java +++ b/media/java/android/media/MediaLibraryService2.java @@ -110,6 +110,11 @@ public abstract class MediaLibraryService2 extends MediaSessionService2 { } public static class MediaLibrarySessionCallback extends MediaSession2.SessionCallback { + + public MediaLibrarySessionCallback(Context context) { + super(context); + } + /** * Called to get the root information for browsing by a particular client. *

diff --git a/media/java/android/media/MediaSession2.java b/media/java/android/media/MediaSession2.java index aa329ab42c27..7eebcdcb0af6 100644 --- a/media/java/android/media/MediaSession2.java +++ b/media/java/android/media/MediaSession2.java @@ -30,6 +30,7 @@ import android.media.session.MediaSession.Callback; import android.media.session.PlaybackState; import android.media.update.ApiLoader; import android.media.update.MediaSession2Provider; +import android.media.update.MediaSession2Provider.CommandProvider; import android.media.update.MediaSession2Provider.ControllerInfoProvider; import android.net.Uri; import android.os.Bundle; @@ -120,43 +121,31 @@ public class MediaSession2 implements AutoCloseable { */ // TODO(jaewan): Move this into the updatable. public static final class Command { - private static final String KEY_COMMAND_CODE - = "android.media.media_session2.command.command_code"; - private static final String KEY_COMMAND_CUSTOM_COMMAND - = "android.media.media_session2.command.custom_command"; - private static final String KEY_COMMAND_EXTRA - = "android.media.media_session2.command.extra"; - - private final int mCommandCode; - // Nonnull if it's custom command - private final String mCustomCommand; - private final Bundle mExtra; - - public Command(int commandCode) { - mCommandCode = commandCode; - mCustomCommand = null; - mExtra = null; + private final CommandProvider mProvider; + + public Command(@NonNull Context context, int commandCode) { + mProvider = ApiLoader.getProvider(context) + .createMediaSession2Command(this, commandCode, null, null); } - public Command(@NonNull String action, @Nullable Bundle extra) { + public Command(@NonNull Context context, @NonNull String action, @Nullable Bundle extra) { if (action == null) { throw new IllegalArgumentException("action shouldn't be null"); } - mCommandCode = COMMAND_CODE_CUSTOM; - mCustomCommand = action; - mExtra = extra; + mProvider = ApiLoader.getProvider(context) + .createMediaSession2Command(this, COMMAND_CODE_CUSTOM, action, extra); } public int getCommandCode() { - return mCommandCode; + return mProvider.getCommandCode_impl(); } public @Nullable String getCustomCommand() { - return mCustomCommand; + return mProvider.getCustomCommand_impl(); } public @Nullable Bundle getExtra() { - return mExtra; + return mProvider.getExtra_impl(); } /** @@ -164,28 +153,15 @@ public class MediaSession2 implements AutoCloseable { * @hide */ public Bundle toBundle() { - Bundle bundle = new Bundle(); - bundle.putInt(KEY_COMMAND_CODE, mCommandCode); - bundle.putString(KEY_COMMAND_CUSTOM_COMMAND, mCustomCommand); - bundle.putBundle(KEY_COMMAND_EXTRA, mExtra); - return bundle; + return mProvider.toBundle_impl(); } /** * @return a new Command instance from the Bundle * @hide */ - public static Command fromBundle(Bundle command) { - int code = command.getInt(KEY_COMMAND_CODE); - if (code != COMMAND_CODE_CUSTOM) { - return new Command(code); - } else { - String customCommand = command.getString(KEY_COMMAND_CUSTOM_COMMAND); - if (customCommand == null) { - return null; - } - return new Command(customCommand, command.getBundle(KEY_COMMAND_EXTRA)); - } + public static Command fromBundle(@NonNull Context context, Bundle command) { + return ApiLoader.getProvider(context).fromBundle_MediaSession2Command(context, command); } @Override @@ -193,18 +169,12 @@ public class MediaSession2 implements AutoCloseable { if (!(obj instanceof Command)) { return false; } - Command other = (Command) obj; - // TODO(jaewan): Should we also compare contents in bundle? - // It may not be possible if the bundle contains private class. - return mCommandCode == other.mCommandCode - && TextUtils.equals(mCustomCommand, other.mCustomCommand); + return mProvider.equals_impl(((Command) obj).mProvider); } @Override public int hashCode() { - final int prime = 31; - return ((mCustomCommand != null) - ? mCustomCommand.hashCode() : 0) * prime + mCommandCode; + return mProvider.hashCode_impl(); } } @@ -216,11 +186,14 @@ public class MediaSession2 implements AutoCloseable { private static final String KEY_COMMANDS = "android.media.mediasession2.commandgroup.commands"; private ArraySet mCommands = new ArraySet<>(); + private final Context mContext; - public CommandGroup() { + public CommandGroup(Context context) { + mContext = context; } - public CommandGroup(CommandGroup others) { + public CommandGroup(Context context, CommandGroup others) { + this(context); mCommands.addAll(others.mCommands); } @@ -230,17 +203,16 @@ public class MediaSession2 implements AutoCloseable { public void addAllPredefinedCommands() { // TODO(jaewan): Is there any better way than this? - mCommands.add(new Command(COMMAND_CODE_PLAYBACK_START)); - mCommands.add(new Command(COMMAND_CODE_PLAYBACK_PAUSE)); - mCommands.add(new Command(COMMAND_CODE_PLAYBACK_STOP)); - mCommands.add(new Command(COMMAND_CODE_PLAYBACK_SKIP_NEXT_ITEM)); - mCommands.add(new Command(COMMAND_CODE_PLAYBACK_SKIP_PREV_ITEM)); - mCommands.add(new Command(COMMAND_CODE_PLAYBACK_PREPARE)); - mCommands.add(new Command(COMMAND_CODE_PLAYBACK_FAST_FORWARD)); - mCommands.add(new Command(COMMAND_CODE_PLAYBACK_REWIND)); - mCommands.add(new Command(COMMAND_CODE_PLAYBACK_SEEK_TO)); - mCommands.add(new Command(COMMAND_CODE_PLAYBACK_SET_CURRENT_PLAYLIST_ITEM)); - mCommands.add(new Command(COMMAND_CODE_PLAYBACK_SET_PLAYLIST_PARAMS)); + mCommands.add(new Command(mContext, COMMAND_CODE_PLAYBACK_START)); + mCommands.add(new Command(mContext, COMMAND_CODE_PLAYBACK_PAUSE)); + mCommands.add(new Command(mContext, COMMAND_CODE_PLAYBACK_STOP)); + mCommands.add(new Command(mContext, COMMAND_CODE_PLAYBACK_SKIP_NEXT_ITEM)); + mCommands.add(new Command(mContext, COMMAND_CODE_PLAYBACK_SKIP_PREV_ITEM)); + mCommands.add(new Command(mContext, COMMAND_CODE_PLAYBACK_PREPARE)); + mCommands.add(new Command(mContext, COMMAND_CODE_PLAYBACK_FAST_FORWARD)); + mCommands.add(new Command(mContext, COMMAND_CODE_PLAYBACK_REWIND)); + mCommands.add(new Command(mContext, COMMAND_CODE_PLAYBACK_SEEK_TO)); + mCommands.add(new Command(mContext, COMMAND_CODE_PLAYBACK_SET_CURRENT_PLAYLIST_ITEM)); } public void removeCommand(Command command) { @@ -281,7 +253,7 @@ public class MediaSession2 implements AutoCloseable { * @return new instance of CommandGroup from the bundle * @hide */ - public static @Nullable CommandGroup fromBundle(Bundle commands) { + public static @Nullable CommandGroup fromBundle(Context context, Bundle commands) { if (commands == null) { return null; } @@ -289,14 +261,14 @@ public class MediaSession2 implements AutoCloseable { if (list == null) { return null; } - CommandGroup commandGroup = new CommandGroup(); + CommandGroup commandGroup = new CommandGroup(context); 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); + Command command = Command.fromBundle(context, commandBundle); if (command != null) { commandGroup.addCommand(command); } @@ -313,6 +285,12 @@ public class MediaSession2 implements AutoCloseable { */ // TODO(jaewan): Can we move this inside of the updatable for default implementation. public static class SessionCallback { + private final Context mContext; + + public SessionCallback(Context context) { + mContext = context; + } + /** * Called when a controller is created for this session. Return allowed commands for * controller. By default it allows all connection requests and commands. @@ -325,7 +303,7 @@ public class MediaSession2 implements AutoCloseable { */ // TODO(jaewan): Change return type. Once we do, null is for reject. public @Nullable CommandGroup onConnect(@NonNull ControllerInfo controller) { - CommandGroup commands = new CommandGroup(); + CommandGroup commands = new CommandGroup(mContext); commands.addAllPredefinedCommands(); return commands; } @@ -611,7 +589,7 @@ public class MediaSession2 implements AutoCloseable { mCallbackExecutor = mContext.getMainExecutor(); } if (mCallback == null) { - mCallback = new SessionCallback(); + mCallback = new SessionCallback(mContext); } return new MediaSession2(mContext, mPlayer, mId, mVolumeProvider, mRatingType, mSessionActivity, mCallbackExecutor, mCallback); @@ -621,7 +599,6 @@ public class MediaSession2 implements AutoCloseable { /** * Information of a controller. */ - // TODO(jaewan): Move implementation to the updatable. public static final class ControllerInfo { private final ControllerInfoProvider mProvider; @@ -788,9 +765,9 @@ public class MediaSession2 implements AutoCloseable { * @hide */ // TODO(jaewan): @SystemApi - public static @Nullable CommandButton fromBundle(Bundle bundle) { + public static @Nullable CommandButton fromBundle(Context context, Bundle bundle) { Builder builder = new Builder(); - builder.setCommand(Command.fromBundle(bundle.getBundle(KEY_COMMAND))); + builder.setCommand(Command.fromBundle(context, bundle.getBundle(KEY_COMMAND))); builder.setIconResId(bundle.getInt(KEY_ICON_RES_ID, 0)); builder.setDisplayName(bundle.getString(KEY_DISPLAY_NAME)); builder.setExtra(bundle.getBundle(KEY_EXTRA)); diff --git a/media/java/android/media/update/MediaSession2Provider.java b/media/java/android/media/update/MediaSession2Provider.java index 8ff0ea53553c..c0c0d80c01b7 100644 --- a/media/java/android/media/update/MediaSession2Provider.java +++ b/media/java/android/media/update/MediaSession2Provider.java @@ -36,6 +36,7 @@ import java.util.concurrent.Executor; /** * @hide */ +// TODO: @SystemApi public interface MediaSession2Provider extends TransportControlProvider { void initialize(); @@ -68,4 +69,14 @@ public interface MediaSession2Provider extends TransportControlProvider { int hashCode_impl(); boolean equals_impl(ControllerInfoProvider obj); } + + interface CommandProvider { + int getCommandCode_impl(); + String getCustomCommand_impl(); + Bundle getExtra_impl(); + Bundle toBundle_impl(); + + boolean equals_impl(Object ob); + int hashCode_impl(); + } } diff --git a/media/java/android/media/update/StaticProvider.java b/media/java/android/media/update/StaticProvider.java index 14b23c8168f6..ef8c9a25c9ac 100644 --- a/media/java/android/media/update/StaticProvider.java +++ b/media/java/android/media/update/StaticProvider.java @@ -37,6 +37,7 @@ import android.media.SessionPlayer2; import android.media.SessionToken2; import android.media.VolumeProvider; import android.media.update.MediaLibraryService2Provider.MediaLibrarySessionProvider; +import android.media.update.MediaSession2Provider.CommandProvider; import android.media.update.MediaSession2Provider.ControllerInfoProvider; import android.os.Bundle; import android.os.IInterface; @@ -66,16 +67,24 @@ public interface StaticProvider { ControllerInfoProvider createMediaSession2ControllerInfoProvider(Context context, MediaSession2.ControllerInfo instance, int uid, int pid, String packageName, IInterface callback); + CommandProvider createMediaSession2Command(MediaSession2.Command instance, + int commandCode, String action, Bundle extra); + MediaSession2.Command fromBundle_MediaSession2Command(Context context, Bundle bundle); + MediaController2Provider createMediaController2(Context context, MediaController2 instance, SessionToken2 token, Executor executor, ControllerCallback callback); + MediaBrowser2Provider createMediaBrowser2(Context context, MediaBrowser2 instance, SessionToken2 token, Executor executor, BrowserCallback callback); + MediaSessionService2Provider createMediaSessionService2(MediaSessionService2 instance); MediaSessionService2Provider createMediaLibraryService2(MediaLibraryService2 instance); + MediaLibrarySessionProvider createMediaLibraryService2MediaLibrarySession(Context context, MediaLibrarySession instance, MediaPlayerInterface player, String id, VolumeProvider volumeProvider, int ratingType, PendingIntent sessionActivity, Executor executor, MediaLibrarySessionCallback callback); + SessionToken2Provider createSessionToken2(Context context, SessionToken2 instance, String packageName, String serviceName, int uid); SessionToken2 SessionToken2_fromBundle(Context context, Bundle bundle); -- 2.11.0