summaryrefslogtreecommitdiff
path: root/android/media/MediaController2.java
diff options
context:
space:
mode:
Diffstat (limited to 'android/media/MediaController2.java')
-rw-r--r--android/media/MediaController2.java565
1 files changed, 410 insertions, 155 deletions
diff --git a/android/media/MediaController2.java b/android/media/MediaController2.java
index d669bc12..591f33f5 100644
--- a/android/media/MediaController2.java
+++ b/android/media/MediaController2.java
@@ -16,18 +16,22 @@
package android.media;
+import static android.media.MediaPlayerBase.BUFFERING_STATE_UNKNOWN;
+
+import android.annotation.CallbackExecutor;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.PendingIntent;
import android.content.Context;
-import android.media.MediaSession2.Command;
+import android.media.MediaPlaylistAgent.RepeatMode;
+import android.media.MediaPlaylistAgent.ShuffleMode;
import android.media.MediaSession2.CommandButton;
-import android.media.MediaSession2.CommandGroup;
import android.media.MediaSession2.ControllerInfo;
-import android.media.MediaSession2.PlaylistParam;
+import android.media.MediaSession2.ErrorCode;
import android.media.session.MediaSessionManager;
import android.media.update.ApiLoader;
import android.media.update.MediaController2Provider;
+import android.media.update.MediaController2Provider.PlaybackInfoProvider;
import android.net.Uri;
import android.os.Bundle;
import android.os.ResultReceiver;
@@ -36,6 +40,7 @@ import java.util.List;
import java.util.concurrent.Executor;
/**
+ * @hide
* Allows an app to interact with an active {@link MediaSession2} or a
* {@link MediaSessionService2} in any status. Media buttons and other commands can be sent to
* the session.
@@ -48,9 +53,9 @@ import java.util.concurrent.Executor;
* <p>
* When controlling {@link MediaSessionService2}, the {@link MediaController2} would be
* available only if the session service allows this controller by
- * {@link MediaSession2.SessionCallback#onConnect(ControllerInfo)} for the service. Wait
- * {@link ControllerCallback#onConnected(CommandGroup)} or
- * {@link ControllerCallback#onDisconnected()} for the result.
+ * {@link MediaSession2.SessionCallback#onConnect(MediaSession2, ControllerInfo)} for the service.
+ * Wait {@link ControllerCallback#onConnected(MediaController2, SessionCommandGroup2)} or
+ * {@link ControllerCallback#onDisconnected(MediaController2)} for the result.
* <p>
* A controller can be created through token from {@link MediaSessionManager} if you hold the
* signature|privileged permission "android.permission.MEDIA_CONTENT_CONTROL" permission or are
@@ -61,10 +66,7 @@ import java.util.concurrent.Executor;
* <p>
* @see MediaSession2
* @see MediaSessionService2
- * @hide
*/
-// TODO(jaewan): Unhide
-// TODO(jaewan): Revisit comments. Currently MediaBrowser case is missing.
public class MediaController2 implements AutoCloseable {
/**
* Interface for listening to change in activeness of the {@link MediaSession2}. It's
@@ -75,9 +77,11 @@ public class MediaController2 implements AutoCloseable {
* Called when the controller is successfully connected to the session. The controller
* becomes available afterwards.
*
+ * @param controller the controller for this event
* @param allowedCommands commands that's allowed by the session.
*/
- public void onConnected(CommandGroup allowedCommands) { }
+ public void onConnected(@NonNull MediaController2 controller,
+ @NonNull SessionCommandGroup2 allowedCommands) { }
/**
* Called when the session refuses the controller or the controller is disconnected from
@@ -86,58 +90,159 @@ public class MediaController2 implements AutoCloseable {
* <p>
* It will be also called after the {@link #close()}, so you can put clean up code here.
* You don't need to call {@link #close()} after this.
+ *
+ * @param controller the controller for this event
+ * @param controller controller for this event
*/
- public void onDisconnected() { }
+ public void onDisconnected(@NonNull MediaController2 controller) { }
/**
* Called when the session set the custom layout through the
* {@link MediaSession2#setCustomLayout(ControllerInfo, List)}.
* <p>
- * Can be called before {@link #onConnected(CommandGroup)} is called.
+ * Can be called before {@link #onConnected(MediaController2, SessionCommandGroup2)} is
+ * called.
*
+ * @param controller the controller for this event
* @param layout
*/
- public void onCustomLayoutChanged(List<CommandButton> layout) { }
+ public void onCustomLayoutChanged(@NonNull MediaController2 controller,
+ @NonNull List<CommandButton> layout) { }
/**
* Called when the session has changed anything related with the {@link PlaybackInfo}.
*
+ * @param controller the controller for this event
* @param info new playback info
*/
- public void onAudioInfoChanged(PlaybackInfo info) { }
+ public void onPlaybackInfoChanged(@NonNull MediaController2 controller,
+ @NonNull PlaybackInfo info) { }
/**
* Called when the allowed commands are changed by session.
*
+ * @param controller the controller for this event
* @param commands newly allowed commands
*/
- public void onAllowedCommandsChanged(CommandGroup commands) { }
+ public void onAllowedCommandsChanged(@NonNull MediaController2 controller,
+ @NonNull SessionCommandGroup2 commands) { }
/**
* Called when the session sent a custom command.
*
+ * @param controller the controller for this event
* @param command
* @param args
* @param receiver
*/
- public void onCustomCommand(Command command, @Nullable Bundle args,
+ public void onCustomCommand(@NonNull MediaController2 controller,
+ @NonNull SessionCommand2 command, @Nullable Bundle args,
@Nullable ResultReceiver receiver) { }
/**
- * Called when the playlist is changed.
+ * Called when the player state is changed.
*
- * @param list
- * @param param
+ * @param controller the controller for this event
+ * @param state
*/
- public void onPlaylistChanged(
- @NonNull List<MediaItem2> list, @NonNull PlaylistParam param) { }
+ public void onPlayerStateChanged(@NonNull MediaController2 controller, int state) { }
/**
- * Called when the playback state is changed.
+ * Called when playback speed is changed.
*
- * @param state
+ * @param controller the controller for this event
+ * @param speed speed
+ */
+ public void onPlaybackSpeedChanged(@NonNull MediaController2 controller,
+ float speed) { }
+
+ /**
+ * Called to report buffering events for a data source.
+ * <p>
+ * Use {@link #getBufferedPosition()} for current buffering position.
+ *
+ * @param controller the controller for this event
+ * @param item the media item for which buffering is happening.
+ * @param state the new buffering state.
+ */
+ public void onBufferingStateChanged(@NonNull MediaController2 controller,
+ @NonNull MediaItem2 item, @MediaPlayerBase.BuffState int state) { }
+
+ /**
+ * Called to indicate that seeking is completed.
+ *
+ * @param controller the controller for this event.
+ * @param position the previous seeking request.
+ */
+ public void onSeekCompleted(@NonNull MediaController2 controller, long position) { }
+
+ /**
+ * Called when a error from
+ *
+ * @param controller the controller for this event
+ * @param errorCode error code
+ * @param extras extra information
+ */
+ public void onError(@NonNull MediaController2 controller, @ErrorCode int errorCode,
+ @Nullable Bundle extras) { }
+
+ /**
+ * Called when the player's currently playing item is changed
+ * <p>
+ * When it's called, you should invalidate previous playback information and wait for later
+ * callbacks.
+ *
+ * @param controller the controller for this event
+ * @param item new item
+ * @see #onBufferingStateChanged(MediaController2, MediaItem2, int)
+ */
+ // TODO(jaewan): Use this (b/74316764)
+ public void onCurrentMediaItemChanged(@NonNull MediaController2 controller,
+ @NonNull MediaItem2 item) { }
+
+ /**
+ * Called when a playlist is changed.
+ *
+ * @param controller the controller for this event
+ * @param list new playlist
+ * @param metadata new metadata
+ */
+ public void onPlaylistChanged(@NonNull MediaController2 controller,
+ @NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata) { }
+
+ /**
+ * Called when a playlist metadata is changed.
+ *
+ * @param controller the controller for this event
+ * @param metadata new metadata
+ */
+ public void onPlaylistMetadataChanged(@NonNull MediaController2 controller,
+ @Nullable MediaMetadata2 metadata) { }
+
+ /**
+ * Called when the shuffle mode is changed.
+ *
+ * @param controller the controller for this event
+ * @param shuffleMode repeat mode
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_NONE
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_ALL
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_GROUP
+ */
+ public void onShuffleModeChanged(@NonNull MediaController2 controller,
+ @MediaPlaylistAgent.ShuffleMode int shuffleMode) { }
+
+ /**
+ * Called when the repeat mode is changed.
+ *
+ * @param controller the controller for this event
+ * @param repeatMode repeat mode
+ * @see MediaPlaylistAgent#REPEAT_MODE_NONE
+ * @see MediaPlaylistAgent#REPEAT_MODE_ONE
+ * @see MediaPlaylistAgent#REPEAT_MODE_ALL
+ * @see MediaPlaylistAgent#REPEAT_MODE_GROUP
*/
- public void onPlaybackStateChanged(@NonNull PlaybackState2 state) { }
+ public void onRepeatModeChanged(@NonNull MediaController2 controller,
+ @MediaPlaylistAgent.RepeatMode int repeatMode) { }
}
/**
@@ -155,21 +260,20 @@ public class MediaController2 implements AutoCloseable {
*/
public static final int PLAYBACK_TYPE_LOCAL = 1;
- private final int mVolumeType;
- private final int mVolumeControl;
- private final int mMaxVolume;
- private final int mCurrentVolume;
- private final AudioAttributes mAudioAttrs;
+ private final PlaybackInfoProvider mProvider;
+
+ /**
+ * @hide
+ */
+ public PlaybackInfo(PlaybackInfoProvider provider) {
+ mProvider = provider;
+ }
/**
* @hide
*/
- public PlaybackInfo(int type, AudioAttributes attrs, int control, int max, int current) {
- mVolumeType = type;
- mAudioAttrs = attrs;
- mVolumeControl = control;
- mMaxVolume = max;
- mCurrentVolume = current;
+ public PlaybackInfoProvider getProvider() {
+ return mProvider;
}
/**
@@ -182,7 +286,7 @@ public class MediaController2 implements AutoCloseable {
* @return The type of playback this session is using.
*/
public int getPlaybackType() {
- return mVolumeType;
+ return mProvider.getPlaybackType_impl();
}
/**
@@ -194,22 +298,21 @@ public class MediaController2 implements AutoCloseable {
* @return The attributes for this session.
*/
public AudioAttributes getAudioAttributes() {
- return mAudioAttrs;
+ return mProvider.getAudioAttributes_impl();
}
/**
* Get the type of volume control that can be used. One of:
* <ul>
- * <li>{@link VolumeProvider#VOLUME_CONTROL_ABSOLUTE}</li>
- * <li>{@link VolumeProvider#VOLUME_CONTROL_RELATIVE}</li>
- * <li>{@link VolumeProvider#VOLUME_CONTROL_FIXED}</li>
+ * <li>{@link VolumeProvider2#VOLUME_CONTROL_ABSOLUTE}</li>
+ * <li>{@link VolumeProvider2#VOLUME_CONTROL_RELATIVE}</li>
+ * <li>{@link VolumeProvider2#VOLUME_CONTROL_FIXED}</li>
* </ul>
*
- * @return The type of volume control that may be used with this
- * session.
+ * @return The type of volume control that may be used with this session.
*/
- public int getVolumeControl() {
- return mVolumeControl;
+ public int getControlType() {
+ return mProvider.getControlType_impl();
}
/**
@@ -218,7 +321,7 @@ public class MediaController2 implements AutoCloseable {
* @return The maximum allowed volume where this session is playing.
*/
public int getMaxVolume() {
- return mMaxVolume;
+ return mProvider.getMaxVolume_impl();
}
/**
@@ -227,39 +330,39 @@ public class MediaController2 implements AutoCloseable {
* @return The current volume where this session is playing.
*/
public int getCurrentVolume() {
- return mCurrentVolume;
+ return mProvider.getCurrentVolume_impl();
}
}
private final MediaController2Provider mProvider;
/**
- * Create a {@link MediaController2} from the {@link SessionToken2}. This connects to the session
- * and may wake up the service if it's not available.
+ * Create a {@link MediaController2} from the {@link SessionToken2}.
+ * This connects to the session and may wake up the service if it's not available.
*
* @param context Context
* @param token token to connect to
- * @param callback controller callback to receive changes in
* @param executor executor to run callbacks on.
+ * @param callback controller callback to receive changes in
*/
- // TODO(jaewan): Put @CallbackExecutor to the constructor.
public MediaController2(@NonNull Context context, @NonNull SessionToken2 token,
- @NonNull ControllerCallback callback, @NonNull Executor executor) {
+ @NonNull @CallbackExecutor Executor executor, @NonNull ControllerCallback callback) {
super();
+ mProvider = createProvider(context, token, executor, callback);
// This also connects to the token.
// Explicit connect() isn't added on purpose because retrying connect() is impossible with
// session whose session binder is only valid while it's active.
// prevent a controller from reusable after the
// session is released and recreated.
- mProvider = createProvider(context, token, callback, executor);
+ mProvider.initialize();
}
MediaController2Provider createProvider(@NonNull Context context,
- @NonNull SessionToken2 token, @NonNull ControllerCallback callback,
- @NonNull Executor executor) {
- return ApiLoader.getProvider(context)
- .createMediaController2(this, context, token, callback, executor);
+ @NonNull SessionToken2 token, @NonNull Executor executor,
+ @NonNull ControllerCallback callback) {
+ return ApiLoader.getProvider().createMediaController2(
+ context, this, token, executor, callback);
}
/**
@@ -281,8 +384,7 @@ public class MediaController2 implements AutoCloseable {
/**
* @return token
*/
- public @NonNull
- SessionToken2 getSessionToken() {
+ public @NonNull SessionToken2 getSessionToken() {
return mProvider.getSessionToken_impl();
}
@@ -305,36 +407,26 @@ public class MediaController2 implements AutoCloseable {
mProvider.stop_impl();
}
- public void skipToPrevious() {
- mProvider.skipToPrevious_impl();
- }
-
- public void skipToNext() {
- mProvider.skipToNext_impl();
- }
-
/**
* Request that the player prepare its playback. In other words, other sessions can continue
* to play during the preparation of this session. This method can be used to speed up the
* start of the playback. Once the preparation is done, the session will change its playback
- * state to {@link PlaybackState2#STATE_PAUSED}. Afterwards, {@link #play} can be called to
- * start playback.
+ * state to {@link MediaPlayerBase#PLAYER_STATE_PAUSED}. Afterwards, {@link #play} can be called
+ * to start playback.
*/
public void prepare() {
mProvider.prepare_impl();
}
/**
- * Start fast forwarding. If playback is already fast forwarding this
- * may increase the rate.
+ * Fast forwards playback. If playback is already fast forwarding this may increase the rate.
*/
public void fastForward() {
mProvider.fastForward_impl();
}
/**
- * Start rewinding. If playback is already rewinding this may increase
- * the rate.
+ * Rewinds playback. If playback is already rewinding this may increase the rate.
*/
public void rewind() {
mProvider.rewind_impl();
@@ -350,20 +442,11 @@ public class MediaController2 implements AutoCloseable {
}
/**
- * Sets the index of current DataSourceDesc in the play list to be played.
- *
- * @param index the index of DataSourceDesc in the play list you want to play
- * @throws IllegalArgumentException if the play list is null
- * @throws NullPointerException if index is outside play list range
- */
- public void setCurrentPlaylistItem(int index) {
- mProvider.setCurrentPlaylistItem_impl(index);
- }
-
- /**
+ * Revisit this API later.
* @hide
*/
public void skipForward() {
+ // TODO(jaewan): (Post-P) Discuss this API later.
// To match with KEYCODE_MEDIA_SKIP_FORWARD
}
@@ -371,6 +454,7 @@ public class MediaController2 implements AutoCloseable {
* @hide
*/
public void skipBackward() {
+ // TODO(jaewan): (Post-P) Discuss this API later.
// To match with KEYCODE_MEDIA_SKIP_BACKWARD
}
@@ -387,12 +471,9 @@ public class MediaController2 implements AutoCloseable {
/**
* Request that the player start playback for a specific search query.
- * An empty or null query should be treated as a request to play any
- * music.
*
- * @param query The search query.
- * @param extras Optional extras that can include extra information
- * about the query.
+ * @param query The search query. Should not be an empty string.
+ * @param extras Optional extras that can include extra information about the query.
*/
public void playFromSearch(@NonNull String query, @Nullable Bundle extras) {
mProvider.playFromSearch_impl(query, extras);
@@ -405,16 +486,15 @@ public class MediaController2 implements AutoCloseable {
* @param extras Optional extras that can include extra information about the media item
* to be played.
*/
- public void playFromUri(@NonNull String uri, @Nullable Bundle extras) {
+ public void playFromUri(@NonNull Uri uri, @Nullable Bundle extras) {
mProvider.playFromUri_impl(uri, extras);
}
-
/**
* Request that the player prepare playback for a specific media id. In other words, other
* sessions can continue to play during the preparation of this session. This method can be
* used to speed up the start of the playback. Once the preparation is done, the session
- * will change its playback state to {@link PlaybackState2#STATE_PAUSED}. Afterwards,
+ * will change its playback state to {@link MediaPlayerBase#PLAYER_STATE_PAUSED}. Afterwards,
* {@link #play} can be called to start playback. If the preparation is not needed,
* {@link #playFromMediaId} can be directly called without this method.
*
@@ -423,21 +503,20 @@ public class MediaController2 implements AutoCloseable {
* to be prepared.
*/
public void prepareFromMediaId(@NonNull String mediaId, @Nullable Bundle extras) {
- mProvider.prepareMediaId_impl(mediaId, extras);
+ mProvider.prepareFromMediaId_impl(mediaId, extras);
}
/**
- * Request that the player prepare playback for a specific search query. An empty or null
- * query should be treated as a request to prepare any music. In other words, other sessions
- * can continue to play during the preparation of this session. This method can be used to
- * speed up the start of the playback. Once the preparation is done, the session will
- * change its playback state to {@link PlaybackState2#STATE_PAUSED}. Afterwards,
+ * Request that the player prepare playback for a specific search query.
+ * In other words, other sessions can continue to play during the preparation of this session.
+ * This method can be used to speed up the start of the playback.
+ * Once the preparation is done, the session will change its playback state to
+ * {@link MediaPlayerBase#PLAYER_STATE_PAUSED}. Afterwards,
* {@link #play} can be called to start playback. If the preparation is not needed,
* {@link #playFromSearch} can be directly called without this method.
*
- * @param query The search query.
- * @param extras Optional extras that can include extra information
- * about the query.
+ * @param query The search query. Should not be an empty string.
+ * @param extras Optional extras that can include extra information about the query.
*/
public void prepareFromSearch(@NonNull String query, @Nullable Bundle extras) {
mProvider.prepareFromSearch_impl(query, extras);
@@ -447,8 +526,8 @@ public class MediaController2 implements AutoCloseable {
* Request that the player prepare playback for a specific {@link Uri}. In other words,
* other sessions can continue to play during the preparation of this session. This method
* can be used to speed up the start of the playback. Once the preparation is done, the
- * session will change its playback state to {@link PlaybackState2#STATE_PAUSED}. Afterwards,
- * {@link #play} can be called to start playback. If the preparation is not needed,
+ * session will change its playback state to {@link MediaPlayerBase#PLAYER_STATE_PAUSED}.
+ * Afterwards, {@link #play} can be called to start playback. If the preparation is not needed,
* {@link #playFromUri} can be directly called without this method.
*
* @param uri The URI of the requested media.
@@ -461,7 +540,7 @@ public class MediaController2 implements AutoCloseable {
/**
* Set the volume of the output this session is playing on. The command will be ignored if it
- * does not support {@link VolumeProvider#VOLUME_CONTROL_ABSOLUTE}.
+ * does not support {@link VolumeProvider2#VOLUME_CONTROL_ABSOLUTE}.
* <p>
* If the session is local playback, this changes the device's volume with the stream that
* session's player is using. Flags will be specified for the {@link AudioManager}.
@@ -483,8 +562,8 @@ public class MediaController2 implements AutoCloseable {
* must be one of {@link AudioManager#ADJUST_LOWER},
* {@link AudioManager#ADJUST_RAISE}, or {@link AudioManager#ADJUST_SAME}.
* The command will be ignored if the session does not support
- * {@link VolumeProvider#VOLUME_CONTROL_RELATIVE} or
- * {@link VolumeProvider#VOLUME_CONTROL_ABSOLUTE}.
+ * {@link VolumeProvider2#VOLUME_CONTROL_RELATIVE} or
+ * {@link VolumeProvider2#VOLUME_CONTROL_ABSOLUTE}.
* <p>
* If the session is local playback, this changes the device's volume with the stream that
* session's player is using. Flags will be specified for the {@link AudioManager}.
@@ -502,39 +581,74 @@ public class MediaController2 implements AutoCloseable {
}
/**
- * Get the rating type supported by the session. One of:
- * <ul>
- * <li>{@link Rating2#RATING_NONE}</li>
- * <li>{@link Rating2#RATING_HEART}</li>
- * <li>{@link Rating2#RATING_THUMB_UP_DOWN}</li>
- * <li>{@link Rating2#RATING_3_STARS}</li>
- * <li>{@link Rating2#RATING_4_STARS}</li>
- * <li>{@link Rating2#RATING_5_STARS}</li>
- * <li>{@link Rating2#RATING_PERCENTAGE}</li>
- * </ul>
+ * Get an intent for launching UI associated with this session if one exists.
*
- * @return The supported rating type
+ * @return A {@link PendingIntent} to launch UI or null.
*/
- public int getRatingType() {
- return mProvider.getRatingType_impl();
+ public @Nullable PendingIntent getSessionActivity() {
+ return mProvider.getSessionActivity_impl();
}
/**
- * Get an intent for launching UI associated with this session if one exists.
+ * Get the lastly cached player state from
+ * {@link ControllerCallback#onPlayerStateChanged(MediaController2, int)}.
*
- * @return A {@link PendingIntent} to launch UI or null.
+ * @return player state
*/
- public @Nullable PendingIntent getSessionActivity() {
- return mProvider.getSessionActivity_impl();
+ public int getPlayerState() {
+ return mProvider.getPlayerState_impl();
+ }
+
+ /**
+ * Gets the current playback position.
+ * <p>
+ * This returns the calculated value of the position, based on the difference between the
+ * update time and current time.
+ *
+ * @return position
+ */
+ public long getCurrentPosition() {
+ return mProvider.getCurrentPosition_impl();
+ }
+
+ /**
+ * Get the lastly cached playback speed from
+ * {@link ControllerCallback#onPlaybackSpeedChanged(MediaController2, float)}.
+ *
+ * @return speed
+ */
+ public float getPlaybackSpeed() {
+ return mProvider.getPlaybackSpeed_impl();
+ }
+
+ /**
+ * Set the playback speed.
+ */
+ public void setPlaybackSpeed(float speed) {
+ // TODO(jaewan): implement this (b/74093080)
+ }
+
+
+ /**
+ * Gets the current buffering state of the player.
+ * During buffering, see {@link #getBufferedPosition()} for the quantifying the amount already
+ * buffered.
+ * @return the buffering state.
+ */
+ public @MediaPlayerBase.BuffState int getBufferingState() {
+ // TODO(jaewan): Implement.
+ return BUFFERING_STATE_UNKNOWN;
}
/**
- * Get the latest {@link PlaybackState2} from the session.
+ * Gets the lastly cached buffered position from the session when
+ * {@link ControllerCallback#onBufferingStateChanged(MediaController2, MediaItem2, int)} is
+ * called.
*
- * @return a playback state
+ * @return buffering position in millis
*/
- public PlaybackState2 getPlaybackState() {
- return mProvider.getPlaybackState_impl();
+ public long getBufferedPosition() {
+ return mProvider.getBufferedPosition_impl();
}
/**
@@ -547,14 +661,19 @@ public class MediaController2 implements AutoCloseable {
}
/**
- * Rate the current content. This will cause the rating to be set for
- * the current user. The Rating type must match the type returned by
- * {@link #getRatingType()}.
+ * Rate the media. This will cause the rating to be set for the current user.
+ * The rating style must follow the user rating style from the session.
+ * You can get the rating style from the session through the
+ * {@link MediaMetadata#getRating(String)} with the key
+ * {@link MediaMetadata#METADATA_KEY_USER_RATING}.
+ * <p>
+ * If the user rating was {@code null}, the media item does not accept setting user rating.
*
- * @param rating The rating to set for the current content
+ * @param mediaId The id of the media
+ * @param rating The rating to set
*/
- public void setRating(Rating2 rating) {
- mProvider.setRating_impl(rating);
+ public void setRating(@NonNull String mediaId, @NonNull Rating2 rating) {
+ mProvider.setRating_impl(mediaId, rating);
}
/**
@@ -564,53 +683,189 @@ public class MediaController2 implements AutoCloseable {
* @param args optional argument
* @param cb optional result receiver
*/
- public void sendCustomCommand(@NonNull Command command, @Nullable Bundle args,
+ public void sendCustomCommand(@NonNull SessionCommand2 command, @Nullable Bundle args,
@Nullable ResultReceiver cb) {
mProvider.sendCustomCommand_impl(command, args, cb);
}
/**
- * Return playlist from the session.
+ * Returns the cached playlist from
+ * {@link ControllerCallback#onPlaylistChanged(MediaController2, List, MediaMetadata2)}.
+ * <p>
+ * This list may differ with the list that was specified with
+ * {@link #setPlaylist(List, MediaMetadata2)} depending on the session implementation. Use media
+ * items returned here for other playlist APIs such as {@link #skipToPlaylistItem(MediaItem2)}.
*
- * @return playlist. Can be {@code null} if the controller doesn't have enough permission.
+ * @return The playlist. Can be {@code null} if the controller doesn't have enough permission or
+ * the session hasn't set any playlist.
*/
public @Nullable List<MediaItem2> getPlaylist() {
return mProvider.getPlaylist_impl();
}
- public @Nullable PlaylistParam getPlaylistParam() {
- return mProvider.getPlaylistParam_impl();
+ /**
+ * Sets the playlist.
+ * <p>
+ * Even when the playlist is successfully set, use the playlist returned from
+ * {@link #getPlaylist()} for playlist APIs such as {@link #skipToPlaylistItem(MediaItem2)}.
+ * Otherwise the session in the remote process can't distinguish between media items.
+ *
+ * @param list playlist
+ * @param metadata metadata of the playlist
+ * @see #getPlaylist()
+ * @see ControllerCallback#onPlaylistChanged(MediaController2, List, MediaMetadata2)
+ */
+ public void setPlaylist(@NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata) {
+ mProvider.setPlaylist_impl(list, metadata);
+ }
+
+ /**
+ * Updates the playlist metadata
+ *
+ * @param metadata metadata of the playlist
+ */
+ public void updatePlaylistMetadata(@Nullable MediaMetadata2 metadata) {
+ mProvider.updatePlaylistMetadata_impl(metadata);
+ }
+
+ /**
+ * Gets the lastly cached playlist playlist metadata either from
+ * {@link ControllerCallback#onPlaylistMetadataChanged(MediaController2, MediaMetadata2)} or
+ * {@link ControllerCallback#onPlaylistChanged(MediaController2, List, MediaMetadata2)}.
+ *
+ * @return metadata metadata of the playlist, or null if none is set
+ */
+ public @Nullable MediaMetadata2 getPlaylistMetadata() {
+ return mProvider.getPlaylistMetadata_impl();
}
+
/**
- * Removes the media item at index in the play list.
+ * Adds the media item to the playlist at position index. Index equals or greater than
+ * the current playlist size will add the item at the end of the playlist.
+ * <p>
+ * This will not change the currently playing media item.
+ * If index is less than or equal to the current index of the playlist,
+ * the current index of the playlist will be incremented correspondingly.
+ *
+ * @param index the index you want to add
+ * @param item the media item you want to add
+ */
+ public void addPlaylistItem(int index, @NonNull MediaItem2 item) {
+ mProvider.addPlaylistItem_impl(index, item);
+ }
+
+ /**
+ * Removes the media item at index in the playlist.
*<p>
- * If index is same as the current index of the playlist, current playback
+ * If the item is the currently playing item of the playlist, current playback
* will be stopped and playback moves to next source in the list.
*
- * @return the removed DataSourceDesc at index in the play list
- * @throws IllegalArgumentException if the play list is null
- * @throws IndexOutOfBoundsException if index is outside play list range
+ * @param item the media item you want to add
*/
- // TODO(jaewan): Remove with index was previously rejected by council (b/36524925)
- // TODO(jaewan): Should we also add movePlaylistItem from index to index?
- public void removePlaylistItem(MediaItem2 item) {
+ public void removePlaylistItem(@NonNull MediaItem2 item) {
mProvider.removePlaylistItem_impl(item);
}
/**
- * Inserts the media item to the play list at position index.
+ * Replace the media item at index in the playlist. This can be also used to update metadata of
+ * an item.
+ *
+ * @param index the index of the item to replace
+ * @param item the new item
+ */
+ public void replacePlaylistItem(int index, @NonNull MediaItem2 item) {
+ mProvider.replacePlaylistItem_impl(index, item);
+ }
+
+ /**
+ * Get the lastly cached current item from
+ * {@link ControllerCallback#onCurrentMediaItemChanged(MediaController2, MediaItem2)}.
+ *
+ * @return index of the current item
+ */
+ public MediaItem2 getCurrentMediaItem() {
+ return mProvider.getCurrentMediaItem_impl();
+ }
+
+ /**
+ * Skips to the previous item in the playlist.
* <p>
- * This will not change the currently playing media item.
- * If index is less than or equal to the current index of the play list,
- * the current index of the play list will be incremented correspondingly.
+ * This calls {@link MediaSession2#skipToPreviousItem()} if the session allows.
+ */
+ public void skipToPreviousItem() {
+ mProvider.skipToPreviousItem_impl();
+ }
+
+ /**
+ * Skips to the next item in the playlist.
+ * <p>
+ * This calls {@link MediaSession2#skipToNextItem()} if the session allows.
+ */
+ public void skipToNextItem() {
+ mProvider.skipToNextItem_impl();
+ }
+
+ /**
+ * Skips to the item in the playlist.
+ * <p>
+ * This calls {@link MediaSession2#skipToPlaylistItem(MediaItem2)} if the session allows.
*
- * @param index the index you want to add dsd to the play list
- * @param item the media item you want to add to the play list
- * @throws IndexOutOfBoundsException if index is outside play list range
- * @throws NullPointerException if dsd is null
+ * @param item The item in the playlist you want to play
*/
- public void addPlaylistItem(int index, MediaItem2 item) {
- mProvider.addPlaylistItem_impl(index, item);
+ public void skipToPlaylistItem(@NonNull MediaItem2 item) {
+ mProvider.skipToPlaylistItem_impl(item);
+ }
+
+ /**
+ * Gets the cached repeat mode from the {@link ControllerCallback#onRepeatModeChanged(
+ * MediaController2, int)}.
+ *
+ * @return repeat mode
+ * @see MediaPlaylistAgent#REPEAT_MODE_NONE
+ * @see MediaPlaylistAgent#REPEAT_MODE_ONE
+ * @see MediaPlaylistAgent#REPEAT_MODE_ALL
+ * @see MediaPlaylistAgent#REPEAT_MODE_GROUP
+ */
+ public @RepeatMode int getRepeatMode() {
+ return mProvider.getRepeatMode_impl();
+ }
+
+ /**
+ * Sets the repeat mode.
+ *
+ * @param repeatMode repeat mode
+ * @see MediaPlaylistAgent#REPEAT_MODE_NONE
+ * @see MediaPlaylistAgent#REPEAT_MODE_ONE
+ * @see MediaPlaylistAgent#REPEAT_MODE_ALL
+ * @see MediaPlaylistAgent#REPEAT_MODE_GROUP
+ */
+ public void setRepeatMode(@RepeatMode int repeatMode) {
+ mProvider.setRepeatMode_impl(repeatMode);
+ }
+
+ /**
+ * Gets the cached shuffle mode from the {@link ControllerCallback#onShuffleModeChanged(
+ * MediaController2, int)}.
+ *
+ * @return The shuffle mode
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_NONE
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_ALL
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_GROUP
+ */
+ public @ShuffleMode int getShuffleMode() {
+ return mProvider.getShuffleMode_impl();
+ }
+
+ /**
+ * Sets the shuffle mode.
+ *
+ * @param shuffleMode The shuffle mode
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_NONE
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_ALL
+ * @see MediaPlaylistAgent#SHUFFLE_MODE_GROUP
+ */
+ public void setShuffleMode(@ShuffleMode int shuffleMode) {
+ mProvider.setShuffleMode_impl(shuffleMode);
}
}