diff options
| author | 2018-11-22 02:13:39 +0000 | |
|---|---|---|
| committer | 2018-11-22 02:13:39 +0000 | |
| commit | e9e01e2cfe6ba7c9e6407b94c32787704acf3e93 (patch) | |
| tree | 618d3e4423beb2fccff03e0ddc48796fbc1cfa52 | |
| parent | ecfc94150087d47e907f7afe466f441b3b85bad7 (diff) | |
| parent | 6f7a0f4650233ed075ca3bddc65286ce95ab6747 (diff) | |
Merge "Remove unused Media 2.0 APIs"
26 files changed, 0 insertions, 5793 deletions
diff --git a/Android.bp b/Android.bp index c3cd4b1d1977..01dfe30833a9 100644 --- a/Android.bp +++ b/Android.bp @@ -456,7 +456,6 @@ java_defaults { "media/java/android/media/IMediaScannerListener.aidl", "media/java/android/media/IMediaScannerService.aidl", "media/java/android/media/IPlaybackConfigDispatcher.aidl", - "media/java/android/media/ISessionTokensListener.aidl", ":libaudioclient_aidl", "media/java/android/media/IRecordingConfigDispatcher.aidl", "media/java/android/media/IRemoteDisplayCallback.aidl", diff --git a/media/java/android/media/ISessionTokensListener.aidl b/media/java/android/media/ISessionTokensListener.aidl deleted file mode 100644 index c83a19e64d66..000000000000 --- a/media/java/android/media/ISessionTokensListener.aidl +++ /dev/null @@ -1,27 +0,0 @@ -/* - * 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 android.media; - -import android.os.Bundle; - -/** - * Listens for changes to the list of session tokens. - * @hide - */ -oneway interface ISessionTokensListener { - void onSessionTokensChanged(in List<Bundle> tokens); -} diff --git a/media/java/android/media/MediaController2.java b/media/java/android/media/MediaController2.java deleted file mode 100644 index a633e5fb129e..000000000000 --- a/media/java/android/media/MediaController2.java +++ /dev/null @@ -1,863 +0,0 @@ -/* - * 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 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.MediaPlaylistAgent.RepeatMode; -import android.media.MediaPlaylistAgent.ShuffleMode; -import android.media.MediaSession2.CommandButton; -import android.media.MediaSession2.ControllerInfo; -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; - -import java.util.List; -import java.util.concurrent.Executor; - -/** - * @hide - * Allows an app to interact with an active {@link MediaSession2} in any status. Media buttons and - * other commands can be sent to the session. - * <p> - * When you're done, use {@link #close()} to clean up resources. This also helps session service - * to be destroyed when there's no controller associated with it. - * <p> - * When controlling {@link MediaSession2}, the controller will be available immediately after - * the creation. - * <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 - * an enabled notification listener or by getting a {@link SessionToken2} directly the - * the session owner. - * <p> - * MediaController2 objects are thread-safe. - * <p> - * @see MediaSession2 - */ -public class MediaController2 implements AutoCloseable { - /** - * Interface for listening to change in activeness of the {@link MediaSession2}. It's - * active if and only if it has set a player. - */ - public abstract static class ControllerCallback { - /** - * 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(@NonNull MediaController2 controller, - @NonNull SessionCommandGroup2 allowedCommands) { } - - /** - * Called when the session refuses the controller or the controller is disconnected from - * the session. The controller becomes unavailable afterwards and the callback wouldn't - * be called. - * <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(@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(MediaController2, SessionCommandGroup2)} is - * called. - * - * @param controller the controller for this event - * @param 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 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(@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(@NonNull MediaController2 controller, - @NonNull SessionCommand2 command, @Nullable Bundle args, - @Nullable ResultReceiver receiver) { } - - /** - * Called when the player state is changed. - * - * @param controller the controller for this event - * @param state - */ - public void onPlayerStateChanged(@NonNull MediaController2 controller, int state) { } - - /** - * Called when playback speed is changed. - * - * @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 onRepeatModeChanged(@NonNull MediaController2 controller, - @MediaPlaylistAgent.RepeatMode int repeatMode) { } - } - - /** - * Holds information about the current playback and how audio is handled for - * this session. - */ - // The same as MediaController.PlaybackInfo - public static final class PlaybackInfo { - /** - * The session uses remote playback. - */ - public static final int PLAYBACK_TYPE_REMOTE = 2; - /** - * The session uses local playback. - */ - public static final int PLAYBACK_TYPE_LOCAL = 1; - - private final PlaybackInfoProvider mProvider; - - /** - * @hide - */ - public PlaybackInfo(PlaybackInfoProvider provider) { - mProvider = provider; - } - - /** - * @hide - */ - public PlaybackInfoProvider getProvider() { - return mProvider; - } - - /** - * Get the type of playback which affects volume handling. One of: - * <ul> - * <li>{@link #PLAYBACK_TYPE_LOCAL}</li> - * <li>{@link #PLAYBACK_TYPE_REMOTE}</li> - * </ul> - * - * @return The type of playback this session is using. - */ - public int getPlaybackType() { - return mProvider.getPlaybackType_impl(); - } - - /** - * Get the audio attributes for this session. The attributes will affect - * volume handling for the session. When the volume type is - * {@link PlaybackInfo#PLAYBACK_TYPE_REMOTE} these may be ignored by the - * remote volume handler. - * - * @return The attributes for this session. - */ - public AudioAttributes getAudioAttributes() { - return mProvider.getAudioAttributes_impl(); - } - - /** - * Get the type of volume control that can be used. One of: - * <ul> - * <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. - */ - public int getControlType() { - return mProvider.getControlType_impl(); - } - - /** - * Get the maximum volume that may be set for this session. - * - * @return The maximum allowed volume where this session is playing. - */ - public int getMaxVolume() { - return mProvider.getMaxVolume_impl(); - } - - /** - * Get the current volume for this session. - * - * @return The current volume where this session is playing. - */ - public int getCurrentVolume() { - 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. - * - * @param context Context - * @param token token to connect to - * @param executor executor to run callbacks on. - * @param callback controller callback to receive changes in - */ - public MediaController2(@NonNull Context context, @NonNull SessionToken2 token, - @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.initialize(); - } - - MediaController2Provider createProvider(@NonNull Context context, - @NonNull SessionToken2 token, @NonNull Executor executor, - @NonNull ControllerCallback callback) { - return ApiLoader.getProvider().createMediaController2( - context, this, token, executor, callback); - } - - /** - * Release this object, and disconnect from the session. After this, callbacks wouldn't be - * received. - */ - @Override - public void close() { - mProvider.close_impl(); - } - - /** - * @hide - */ - public MediaController2Provider getProvider() { - return mProvider; - } - - /** - * @return token - */ - public @NonNull SessionToken2 getSessionToken() { - return mProvider.getSessionToken_impl(); - } - - /** - * Returns whether this class is connected to active {@link MediaSession2} or not. - */ - public boolean isConnected() { - return mProvider.isConnected_impl(); - } - - public void play() { - mProvider.play_impl(); - } - - public void pause() { - mProvider.pause_impl(); - } - - public void stop() { - mProvider.stop_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 MediaPlayerBase#PLAYER_STATE_PAUSED}. Afterwards, {@link #play} can be called - * to start playback. - */ - public void prepare() { - mProvider.prepare_impl(); - } - - /** - * Fast forwards playback. If playback is already fast forwarding this may increase the rate. - */ - public void fastForward() { - mProvider.fastForward_impl(); - } - - /** - * Rewinds playback. If playback is already rewinding this may increase the rate. - */ - public void rewind() { - mProvider.rewind_impl(); - } - - /** - * Move to a new location in the media stream. - * - * @param pos Position to move to, in milliseconds. - */ - public void seekTo(long pos) { - mProvider.seekTo_impl(pos); - } - - /** - * Revisit this API later. - * @hide - */ - public void skipForward() { - // TODO(jaewan): (Post-P) Discuss this API later. - // To match with KEYCODE_MEDIA_SKIP_FORWARD - } - - /** - * @hide - */ - public void skipBackward() { - // TODO(jaewan): (Post-P) Discuss this API later. - // To match with KEYCODE_MEDIA_SKIP_BACKWARD - } - - /** - * Request that the player start playback for a specific media id. - * - * @param mediaId The id of the requested media. - * @param extras Optional extras that can include extra information about the media item - * to be played. - */ - public void playFromMediaId(@NonNull String mediaId, @Nullable Bundle extras) { - mProvider.playFromMediaId_impl(mediaId, extras); - } - - /** - * Request that the player start playback for a specific search 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); - } - - /** - * Request that the player start playback for a specific {@link Uri}. - * - * @param uri The URI of the requested media. - * @param extras Optional extras that can include extra information about the media item - * to be played. - */ - 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 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. - * - * @param mediaId The id of the requested media. - * @param extras Optional extras that can include extra information about the media item - * to be prepared. - */ - public void prepareFromMediaId(@NonNull String mediaId, @Nullable Bundle extras) { - mProvider.prepareFromMediaId_impl(mediaId, extras); - } - - /** - * 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. 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); - } - - /** - * 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 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. - * @param extras Optional extras that can include extra information about the media item - * to be prepared. - */ - public void prepareFromUri(@NonNull Uri uri, @Nullable Bundle extras) { - mProvider.prepareFromUri_impl(uri, extras); - } - - /** - * Set the volume of the output this session is playing on. The command will be ignored if it - * 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}. - * <p> - * If the session is remote player (i.e. session has set volume provider), its volume provider - * will receive this request instead. - * - * @see #getPlaybackInfo() - * @param value The value to set it to, between 0 and the reported max. - * @param flags flags from {@link AudioManager} to include with the volume request for local - * playback - */ - public void setVolumeTo(int value, int flags) { - mProvider.setVolumeTo_impl(value, flags); - } - - /** - * Adjust the volume of the output this session is playing on. The direction - * 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 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}. - * <p> - * If the session is remote player (i.e. session has set volume provider), its volume provider - * will receive this request instead. - * - * @see #getPlaybackInfo() - * @param direction The direction to adjust the volume in. - * @param flags flags from {@link AudioManager} to include with the volume request for local - * playback - */ - public void adjustVolume(int direction, int flags) { - mProvider.adjustVolume_impl(direction, flags); - } - - /** - * Get an intent for launching UI associated with this session if one exists. - * - * @return A {@link PendingIntent} to launch UI or null. - */ - public @Nullable PendingIntent getSessionActivity() { - return mProvider.getSessionActivity_impl(); - } - - /** - * Get the lastly cached player state from - * {@link ControllerCallback#onPlayerStateChanged(MediaController2, int)}. - * - * @return player state - */ - 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; - } - - /** - * Gets the lastly cached buffered position from the session when - * {@link ControllerCallback#onBufferingStateChanged(MediaController2, MediaItem2, int)} is - * called. - * - * @return buffering position in millis - */ - public long getBufferedPosition() { - return mProvider.getBufferedPosition_impl(); - } - - /** - * Get the current playback info for this session. - * - * @return The current playback info or null. - */ - public @Nullable PlaybackInfo getPlaybackInfo() { - return mProvider.getPlaybackInfo_impl(); - } - - /** - * 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 mediaId The id of the media - * @param rating The rating to set - */ - public void setRating(@NonNull String mediaId, @NonNull Rating2 rating) { - mProvider.setRating_impl(mediaId, rating); - } - - /** - * Send custom command to the session - * - * @param command custom command - * @param args optional argument - * @param cb optional result receiver - */ - public void sendCustomCommand(@NonNull SessionCommand2 command, @Nullable Bundle args, - @Nullable ResultReceiver cb) { - mProvider.sendCustomCommand_impl(command, args, cb); - } - - /** - * 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 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(); - } - - /** - * 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(); - } - - - /** - * 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 the item is the currently playing item of the playlist, current playback - * will be stopped and playback moves to next source in the list. - * - * @param item the media item you want to add - */ - public void removePlaylistItem(@NonNull MediaItem2 item) { - mProvider.removePlaylistItem_impl(item); - } - - /** - * 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 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 item The item in the playlist you want to play - */ - 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); - } -} diff --git a/media/java/android/media/MediaItem2.java b/media/java/android/media/MediaItem2.java deleted file mode 100644 index 423a1fd4479c..000000000000 --- a/media/java/android/media/MediaItem2.java +++ /dev/null @@ -1,220 +0,0 @@ -/* - * 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 android.media; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.media.update.ApiLoader; -import android.media.update.MediaItem2Provider; -import android.os.Bundle; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @hide - * A class with information on a single media item with the metadata information. - * Media item are application dependent so we cannot guarantee that they contain the right values. - * <p> - * When it's sent to a controller or browser, it's anonymized and data descriptor wouldn't be sent. - * <p> - * This object isn't a thread safe. - */ -public class MediaItem2 { - /** @hide */ - @Retention(RetentionPolicy.SOURCE) - @IntDef(flag=true, value = { FLAG_BROWSABLE, FLAG_PLAYABLE }) - public @interface Flags { } - - /** - * Flag: Indicates that the item has children of its own. - */ - public static final int FLAG_BROWSABLE = 1 << 0; - - /** - * Flag: Indicates that the item is playable. - * <p> - * The id of this item may be passed to - * {@link MediaController2#playFromMediaId(String, Bundle)} - */ - public static final int FLAG_PLAYABLE = 1 << 1; - - private final MediaItem2Provider mProvider; - - /** - * Create a new media item - * @hide - */ - public MediaItem2(MediaItem2Provider provider) { - mProvider = provider; - } - - /** - * @hide - */ - public MediaItem2Provider getProvider() { - return mProvider; - } - - /** - * Return this object as a bundle to share between processes. - * - * @return a new bundle instance - */ - public Bundle toBundle() { - return mProvider.toBundle_impl(); - } - - public static MediaItem2 fromBundle(Bundle bundle) { - return ApiLoader.getProvider().fromBundle_MediaItem2(bundle); - } - - public String toString() { - return mProvider.toString_impl(); - } - - /** - * Gets the flags of the item. - */ - public @Flags int getFlags() { - return mProvider.getFlags_impl(); - } - - /** - * Returns whether this item is browsable. - * @see #FLAG_BROWSABLE - */ - public boolean isBrowsable() { - return mProvider.isBrowsable_impl(); - } - - /** - * Returns whether this item is playable. - * @see #FLAG_PLAYABLE - */ - public boolean isPlayable() { - return mProvider.isPlayable_impl(); - } - - /** - * Set a metadata. If the metadata is not null, its id should be matched with this instance's - * media id. - * - * @param metadata metadata to update - */ - public void setMetadata(@Nullable MediaMetadata2 metadata) { - mProvider.setMetadata_impl(metadata); - } - - /** - * Returns the metadata of the media. - */ - public @Nullable MediaMetadata2 getMetadata() { - return mProvider.getMetadata_impl(); - } - - /** - * Returns the media id for this item. - */ - public @NonNull String getMediaId() { - return mProvider.getMediaId_impl(); - } - - /** - * Return the {@link DataSourceDesc} - * <p> - * Can be {@code null} if the MediaItem2 came from another process and anonymized - * - * @return data source descriptor - */ - public @Nullable DataSourceDesc getDataSourceDesc() { - return mProvider.getDataSourceDesc_impl(); - } - - @Override - public boolean equals(Object obj) { - return mProvider.equals_impl(obj); - } - - /** - * Build {@link MediaItem2} - */ - public static final class Builder { - private final MediaItem2Provider.BuilderProvider mProvider; - - /** - * Constructor for {@link Builder} - * - * @param flags - */ - public Builder(@Flags int flags) { - mProvider = ApiLoader.getProvider().createMediaItem2Builder(this, flags); - } - - /** - * Set the media id of this instance. {@code null} for unset. - * <p> - * Media id is used to identify a media contents between session and controller. - * <p> - * If the metadata is set with the {@link #setMetadata(MediaMetadata2)} and it has - * media id, id from {@link #setMediaId(String)} will be ignored and metadata's id will be - * used instead. If the id isn't set neither by {@link #setMediaId(String)} nor - * {@link #setMetadata(MediaMetadata2)}, id will be automatically generated. - * - * @param mediaId media id - * @return this instance for chaining - */ - public Builder setMediaId(@Nullable String mediaId) { - return mProvider.setMediaId_impl(mediaId); - } - - /** - * Set the metadata of this instance. {@code null} for unset. - * <p> - * If the metadata is set with the {@link #setMetadata(MediaMetadata2)} and it has - * media id, id from {@link #setMediaId(String)} will be ignored and metadata's id will be - * used instead. If the id isn't set neither by {@link #setMediaId(String)} nor - * {@link #setMetadata(MediaMetadata2)}, id will be automatically generated. - * - * @param metadata metadata - * @return this instance for chaining - */ - public Builder setMetadata(@Nullable MediaMetadata2 metadata) { - return mProvider.setMetadata_impl(metadata); - } - - /** - * Set the data source descriptor for this instance. {@code null} for unset. - * - * @param dataSourceDesc data source descriptor - * @return this instance for chaining - */ - public Builder setDataSourceDesc(@Nullable DataSourceDesc dataSourceDesc) { - return mProvider.setDataSourceDesc_impl(dataSourceDesc); - } - - /** - * Build {@link MediaItem2}. - * - * @return a new {@link MediaItem2}. - */ - public MediaItem2 build() { - return mProvider.build_impl(); - } - } -} diff --git a/media/java/android/media/MediaMetadata2.java b/media/java/android/media/MediaMetadata2.java deleted file mode 100644 index 7b03ae0ca424..000000000000 --- a/media/java/android/media/MediaMetadata2.java +++ /dev/null @@ -1,854 +0,0 @@ -/* - * 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 android.media; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.StringDef; -import android.graphics.Bitmap; -import android.media.update.ApiLoader; -import android.media.update.MediaMetadata2Provider; -import android.net.Uri; -import android.os.Bundle; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.Set; - -/** - * @hide - * Contains metadata about an item, such as the title, artist, etc. - */ -// New version of MediaMetadata with following changes -// - Don't implement Parcelable for updatable support. -// - Also support MediaDescription features. MediaDescription is deprecated instead because -// it was insufficient for controller to display media contents. -public final class MediaMetadata2 { - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the title of the media. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_TITLE = "android.media.metadata.TITLE"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the artist of the media. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST"; - - /** - * The metadata key for a {@link Long} typed value to retrieve the information about the - * duration of the media in ms. A negative duration indicates that the duration is unknown - * (or infinite). - * - * @see Builder#putLong(String, long) - * @see #getLong(String) - */ - public static final String METADATA_KEY_DURATION = "android.media.metadata.DURATION"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the album title for the media. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_ALBUM = "android.media.metadata.ALBUM"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the author of the media. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_AUTHOR = "android.media.metadata.AUTHOR"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the writer of the media. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_WRITER = "android.media.metadata.WRITER"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the composer of the media. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the compilation status of the media. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_COMPILATION = "android.media.metadata.COMPILATION"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the date the media was created or published. - * The format is unspecified but RFC 3339 is recommended. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_DATE = "android.media.metadata.DATE"; - - /** - * The metadata key for a {@link Long} typed value to retrieve the information about the year - * the media was created or published. - * - * @see Builder#putLong(String, long) - * @see #getLong(String) - */ - public static final String METADATA_KEY_YEAR = "android.media.metadata.YEAR"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the genre of the media. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_GENRE = "android.media.metadata.GENRE"; - - /** - * The metadata key for a {@link Long} typed value to retrieve the information about the - * track number for the media. - * - * @see Builder#putLong(String, long) - * @see #getLong(String) - */ - public static final String METADATA_KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER"; - - /** - * The metadata key for a {@link Long} typed value to retrieve the information about the - * number of tracks in the media's original source. - * - * @see Builder#putLong(String, long) - * @see #getLong(String) - */ - public static final String METADATA_KEY_NUM_TRACKS = "android.media.metadata.NUM_TRACKS"; - - /** - * The metadata key for a {@link Long} typed value to retrieve the information about the - * disc number for the media's original source. - * - * @see Builder#putLong(String, long) - * @see #getLong(String) - */ - public static final String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the artist for the album of the media's original source. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST"; - - /** - * The metadata key for a {@link Bitmap} typed value to retrieve the information about the - * artwork for the media. - * The artwork should be relatively small and may be scaled down if it is too large. - * For higher resolution artwork, {@link #METADATA_KEY_ART_URI} should be used instead. - * - * @see Builder#putBitmap(String, Bitmap) - * @see #getBitmap(String) - */ - public static final String METADATA_KEY_ART = "android.media.metadata.ART"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about Uri of the artwork for the media. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_ART_URI = "android.media.metadata.ART_URI"; - - /** - * The metadata key for a {@link Bitmap} typed value to retrieve the information about the - * artwork for the album of the media's original source. - * The artwork should be relatively small and may be scaled down if it is too large. - * For higher resolution artwork, {@link #METADATA_KEY_ALBUM_ART_URI} should be used instead. - * - * @see Builder#putBitmap(String, Bitmap) - * @see #getBitmap(String) - */ - public static final String METADATA_KEY_ALBUM_ART = "android.media.metadata.ALBUM_ART"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the Uri of the artwork for the album of the media's original source. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_ALBUM_ART_URI = "android.media.metadata.ALBUM_ART_URI"; - - /** - * The metadata key for a {@link Rating2} typed value to retrieve the information about the - * user's rating for the media. - * - * @see Builder#putRating(String, Rating2) - * @see #getRating(String) - */ - public static final String METADATA_KEY_USER_RATING = "android.media.metadata.USER_RATING"; - - /** - * The metadata key for a {@link Rating2} typed value to retrieve the information about the - * overall rating for the media. - * - * @see Builder#putRating(String, Rating2) - * @see #getRating(String) - */ - public static final String METADATA_KEY_RATING = "android.media.metadata.RATING"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the title that is suitable for display to the user. - * It will generally be the same as {@link #METADATA_KEY_TITLE} but may differ for some formats. - * When displaying media described by this metadata, this should be preferred if present. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_DISPLAY_TITLE = "android.media.metadata.DISPLAY_TITLE"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the subtitle that is suitable for display to the user. - * When displaying a second line for media described by this metadata, this should be preferred - * to other fields if present. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_DISPLAY_SUBTITLE - = "android.media.metadata.DISPLAY_SUBTITLE"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the description that is suitable for display to the user. - * When displaying more information for media described by this metadata, - * this should be preferred to other fields if present. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_DISPLAY_DESCRIPTION - = "android.media.metadata.DISPLAY_DESCRIPTION"; - - /** - * The metadata key for a {@link Bitmap} typed value to retrieve the information about the icon - * or thumbnail that is suitable for display to the user. - * When displaying an icon for media described by this metadata, this should be preferred to - * other fields if present. - * <p> - * The icon should be relatively small and may be scaled down if it is too large. - * For higher resolution artwork, {@link #METADATA_KEY_DISPLAY_ICON_URI} should be used instead. - * - * @see Builder#putBitmap(String, Bitmap) - * @see #getBitmap(String) - */ - public static final String METADATA_KEY_DISPLAY_ICON = "android.media.metadata.DISPLAY_ICON"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the Uri of icon or thumbnail that is suitable for display to the user. - * When displaying more information for media described by this metadata, the - * display description should be preferred to other fields when present. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_DISPLAY_ICON_URI - = "android.media.metadata.DISPLAY_ICON_URI"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the media ID of the content. This value is specific to the - * service providing the content. If used, this should be a persistent - * unique key for the underlying content. It may be used with - * {@link MediaController2#playFromMediaId(String, Bundle)} - * to initiate playback when provided by a {@link MediaBrowser2} connected to - * the same app. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_MEDIA_ID = "android.media.metadata.MEDIA_ID"; - - /** - * The metadata key for a {@link CharSequence} or {@link String} typed value to retrieve the - * information about the Uri of the content. This value is specific to the service providing the - * content. It may be used with {@link MediaController2#playFromUri(Uri, Bundle)} - * to initiate playback when provided by a {@link MediaBrowser2} connected to the same app. - * - * @see Builder#putText(String, CharSequence) - * @see Builder#putString(String, String) - * @see #getText(String) - * @see #getString(String) - */ - public static final String METADATA_KEY_MEDIA_URI = "android.media.metadata.MEDIA_URI"; - - /** - * The metadata key for a {@link Long} typed value to retrieve the information about the - * bluetooth folder type of the media specified in the section 6.10.2.2 of the Bluetooth - * AVRCP 1.5. It should be one of the following: - * <ul> - * <li>{@link #BT_FOLDER_TYPE_MIXED}</li> - * <li>{@link #BT_FOLDER_TYPE_TITLES}</li> - * <li>{@link #BT_FOLDER_TYPE_ALBUMS}</li> - * <li>{@link #BT_FOLDER_TYPE_ARTISTS}</li> - * <li>{@link #BT_FOLDER_TYPE_GENRES}</li> - * <li>{@link #BT_FOLDER_TYPE_PLAYLISTS}</li> - * <li>{@link #BT_FOLDER_TYPE_YEARS}</li> - * </ul> - * - * @see Builder#putLong(String, long) - * @see #getLong(String) - */ - public static final String METADATA_KEY_BT_FOLDER_TYPE - = "android.media.metadata.BT_FOLDER_TYPE"; - - /** - * The type of folder that is unknown or contains media elements of mixed types as specified in - * the section 6.10.2.2 of the Bluetooth AVRCP 1.5. - */ - public static final long BT_FOLDER_TYPE_MIXED = 0; - - /** - * The type of folder that contains media elements only as specified in the section 6.10.2.2 of - * the Bluetooth AVRCP 1.5. - */ - public static final long BT_FOLDER_TYPE_TITLES = 1; - - /** - * The type of folder that contains folders categorized by album as specified in the section - * 6.10.2.2 of the Bluetooth AVRCP 1.5. - */ - public static final long BT_FOLDER_TYPE_ALBUMS = 2; - - /** - * The type of folder that contains folders categorized by artist as specified in the section - * 6.10.2.2 of the Bluetooth AVRCP 1.5. - */ - public static final long BT_FOLDER_TYPE_ARTISTS = 3; - - /** - * The type of folder that contains folders categorized by genre as specified in the section - * 6.10.2.2 of the Bluetooth AVRCP 1.5. - */ - public static final long BT_FOLDER_TYPE_GENRES = 4; - - /** - * The type of folder that contains folders categorized by playlist as specified in the section - * 6.10.2.2 of the Bluetooth AVRCP 1.5. - */ - public static final long BT_FOLDER_TYPE_PLAYLISTS = 5; - - /** - * The type of folder that contains folders categorized by year as specified in the section - * 6.10.2.2 of the Bluetooth AVRCP 1.5. - */ - public static final long BT_FOLDER_TYPE_YEARS = 6; - - /** - * The metadata key for a {@link Long} typed value to retrieve the information about whether - * the media is an advertisement. A value of 0 indicates it is not an advertisement. - * A value of 1 or non-zero indicates it is an advertisement. - * If not specified, this value is set to 0 by default. - * - * @see Builder#putLong(String, long) - * @see #getLong(String) - */ - public static final String METADATA_KEY_ADVERTISEMENT = "android.media.metadata.ADVERTISEMENT"; - - /** - * The metadata key for a {@link Long} typed value to retrieve the information about the - * download status of the media which will be used for later offline playback. It should be - * one of the following: - * - * <ul> - * <li>{@link #STATUS_NOT_DOWNLOADED}</li> - * <li>{@link #STATUS_DOWNLOADING}</li> - * <li>{@link #STATUS_DOWNLOADED}</li> - * </ul> - * - * @see Builder#putLong(String, long) - * @see #getLong(String) - */ - public static final String METADATA_KEY_DOWNLOAD_STATUS = - "android.media.metadata.DOWNLOAD_STATUS"; - - /** - * The status value to indicate the media item is not downloaded. - * - * @see #METADATA_KEY_DOWNLOAD_STATUS - */ - public static final long STATUS_NOT_DOWNLOADED = 0; - - /** - * The status value to indicate the media item is being downloaded. - * - * @see #METADATA_KEY_DOWNLOAD_STATUS - */ - public static final long STATUS_DOWNLOADING = 1; - - /** - * The status value to indicate the media item is downloaded for later offline playback. - * - * @see #METADATA_KEY_DOWNLOAD_STATUS - */ - public static final long STATUS_DOWNLOADED = 2; - - /** - * A {@link Bundle} extra. - */ - public static final String METADATA_KEY_EXTRAS = "android.media.metadata.EXTRAS"; - - /** - * @hide - */ - @StringDef({METADATA_KEY_TITLE, METADATA_KEY_ARTIST, METADATA_KEY_ALBUM, METADATA_KEY_AUTHOR, - METADATA_KEY_WRITER, METADATA_KEY_COMPOSER, METADATA_KEY_COMPILATION, - METADATA_KEY_DATE, METADATA_KEY_GENRE, METADATA_KEY_ALBUM_ARTIST, METADATA_KEY_ART_URI, - METADATA_KEY_ALBUM_ART_URI, METADATA_KEY_DISPLAY_TITLE, METADATA_KEY_DISPLAY_SUBTITLE, - METADATA_KEY_DISPLAY_DESCRIPTION, METADATA_KEY_DISPLAY_ICON_URI, - METADATA_KEY_MEDIA_ID, METADATA_KEY_MEDIA_URI}) - @Retention(RetentionPolicy.SOURCE) - public @interface TextKey {} - - /** - * @hide - */ - @StringDef({METADATA_KEY_DURATION, METADATA_KEY_YEAR, METADATA_KEY_TRACK_NUMBER, - METADATA_KEY_NUM_TRACKS, METADATA_KEY_DISC_NUMBER, METADATA_KEY_BT_FOLDER_TYPE, - METADATA_KEY_ADVERTISEMENT, METADATA_KEY_DOWNLOAD_STATUS}) - @Retention(RetentionPolicy.SOURCE) - public @interface LongKey {} - - /** - * @hide - */ - @StringDef({METADATA_KEY_ART, METADATA_KEY_ALBUM_ART, METADATA_KEY_DISPLAY_ICON}) - @Retention(RetentionPolicy.SOURCE) - public @interface BitmapKey {} - - /** - * @hide - */ - @StringDef({METADATA_KEY_USER_RATING, METADATA_KEY_RATING}) - @Retention(RetentionPolicy.SOURCE) - public @interface RatingKey {} - - /** - * @hide - */ - // TODO(jaewan): Add predefined float key. - @Retention(RetentionPolicy.SOURCE) - public @interface FloatKey {} - - private final MediaMetadata2Provider mProvider; - - /** - * @hide - */ - public MediaMetadata2(MediaMetadata2Provider provider) { - mProvider = provider; - } - - /** - * Returns true if the given key is contained in the metadata - * - * @param key a String key - * @return true if the key exists in this metadata, false otherwise - */ - public boolean containsKey(@NonNull String key) { - return mProvider.containsKey_impl(key); - } - - /** - * Returns the value associated with the given key, or null if no mapping of - * the desired type exists for the given key or a null value is explicitly - * associated with the key. - * - * @param key The key the value is stored under - * @return a CharSequence value, or null - */ - public @Nullable CharSequence getText(@NonNull @TextKey String key) { - return mProvider.getText_impl(key); - } - - /** - * Returns the media id, or {@code null} if the id doesn't exist. - *<p> - * This is equivalent to the {@link #getString(String)} with the {@link #METADATA_KEY_MEDIA_ID}. - * - * @return media id. Can be {@code null} - * @see #METADATA_KEY_MEDIA_ID - */ - public @Nullable String getMediaId() { - return mProvider.getMediaId_impl(); - } - - /** - * Returns the value associated with the given key, or null if no mapping of - * the desired type exists for the given key or a null value is explicitly - * associated with the key. - * - * @param key The key the value is stored under - * @return a String value, or null - */ - public @Nullable String getString(@NonNull @TextKey String key) { - return mProvider.getString_impl(key); - } - - /** - * Returns the value associated with the given key, or 0L if no long exists - * for the given key. - * - * @param key The key the value is stored under - * @return a long value - */ - public long getLong(@NonNull @LongKey String key) { - return mProvider.getLong_impl(key); - } - - /** - * Return a {@link Rating2} for the given key or null if no rating exists for - * the given key. - * <p> - * For the {@link #METADATA_KEY_USER_RATING}, A {@code null} return value means that user rating - * cannot be set by {@link MediaController2}. - * - * @param key The key the value is stored under - * @return A {@link Rating2} or {@code null} - */ - public @Nullable Rating2 getRating(@NonNull @RatingKey String key) { - return mProvider.getRating_impl(key); - } - - /** - * Return a {@link Bitmap} for the given key or null if no bitmap exists for - * the given key. - * - * @param key The key the value is stored under - * @return A {@link Bitmap} or null - */ - public @Nullable Bitmap getBitmap(@NonNull @BitmapKey String key) { - return mProvider.getBitmap_impl(key); - } - - /** - * Return the value associated with the given key, or 0.0f if no long exists - * for the given key. - * - * @param key The key the value is stored under - * @return a float value - */ - public float getFloat(@NonNull @FloatKey String key) { - return mProvider.getFloat_impl(key); - } - - /** - * Get the extra {@link Bundle} from the metadata object. - * - * @return A {@link Bundle} or {@code null} - */ - public @Nullable Bundle getExtras() { - return mProvider.getExtras_impl(); - } - - /** - * Get the number of fields in this metadata. - * - * @return The number of fields in the metadata. - */ - public int size() { - return mProvider.size_impl(); - } - - /** - * Returns a Set containing the Strings used as keys in this metadata. - * - * @return a Set of String keys - */ - public @NonNull Set<String> keySet() { - return mProvider.keySet_impl(); - } - - /** - * Gets the bundle backing the metadata object. This is available to support - * backwards compatibility. Apps should not modify the bundle directly. - * - * @return The Bundle backing this metadata. - */ - public @NonNull Bundle toBundle() { - return mProvider.toBundle_impl(); - } - - /** - * Creates the {@link MediaMetadata2} from the bundle that previously returned by - * {@link #toBundle()}. - * - * @param bundle bundle for the metadata - * @return a new MediaMetadata2 - */ - public static @NonNull MediaMetadata2 fromBundle(@Nullable Bundle bundle) { - return ApiLoader.getProvider().fromBundle_MediaMetadata2(bundle); - } - - /** - * Use to build MediaMetadata2 objects. The system defined metadata keys must - * use the appropriate data type. - */ - public static final class Builder { - private final MediaMetadata2Provider.BuilderProvider mProvider; - - /** - * Create an empty Builder. Any field that should be included in the - * {@link MediaMetadata2} must be added. - */ - public Builder() { - mProvider = ApiLoader.getProvider().createMediaMetadata2Builder(this); - } - - /** - * Create a Builder using a {@link MediaMetadata2} instance to set the - * initial values. All fields in the source metadata will be included in - * the new metadata. Fields can be overwritten by adding the same key. - * - * @param source - */ - public Builder(@NonNull MediaMetadata2 source) { - mProvider = ApiLoader.getProvider().createMediaMetadata2Builder(this, source); - } - - /** - * @hide - */ - public Builder(@NonNull MediaMetadata2Provider.BuilderProvider provider) { - mProvider = provider; - } - - /** - * Put a CharSequence value into the metadata. Custom keys may be used, - * but if the METADATA_KEYs defined in this class are used they may only - * be one of the following: - * <ul> - * <li>{@link #METADATA_KEY_TITLE}</li> - * <li>{@link #METADATA_KEY_ARTIST}</li> - * <li>{@link #METADATA_KEY_ALBUM}</li> - * <li>{@link #METADATA_KEY_AUTHOR}</li> - * <li>{@link #METADATA_KEY_WRITER}</li> - * <li>{@link #METADATA_KEY_COMPOSER}</li> - * <li>{@link #METADATA_KEY_DATE}</li> - * <li>{@link #METADATA_KEY_GENRE}</li> - * <li>{@link #METADATA_KEY_ALBUM_ARTIST}</li> - * <li>{@link #METADATA_KEY_ART_URI}</li> - * <li>{@link #METADATA_KEY_ALBUM_ART_URI}</li> - * <li>{@link #METADATA_KEY_DISPLAY_TITLE}</li> - * <li>{@link #METADATA_KEY_DISPLAY_SUBTITLE}</li> - * <li>{@link #METADATA_KEY_DISPLAY_DESCRIPTION}</li> - * <li>{@link #METADATA_KEY_DISPLAY_ICON_URI}</li> - * </ul> - * - * @param key The key for referencing this value - * @param value The CharSequence value to store - * @return The Builder to allow chaining - */ - public @NonNull Builder putText(@NonNull @TextKey String key, - @Nullable CharSequence value) { - return mProvider.putText_impl(key, value); - } - - /** - * Put a String value into the metadata. Custom keys may be used, but if - * the METADATA_KEYs defined in this class are used they may only be one - * of the following: - * <ul> - * <li>{@link #METADATA_KEY_TITLE}</li> - * <li>{@link #METADATA_KEY_ARTIST}</li> - * <li>{@link #METADATA_KEY_ALBUM}</li> - * <li>{@link #METADATA_KEY_AUTHOR}</li> - * <li>{@link #METADATA_KEY_WRITER}</li> - * <li>{@link #METADATA_KEY_COMPOSER}</li> - * <li>{@link #METADATA_KEY_DATE}</li> - * <li>{@link #METADATA_KEY_GENRE}</li> - * <li>{@link #METADATA_KEY_ALBUM_ARTIST}</li> - * <li>{@link #METADATA_KEY_ART_URI}</li> - * <li>{@link #METADATA_KEY_ALBUM_ART_URI}</li> - * <li>{@link #METADATA_KEY_DISPLAY_TITLE}</li> - * <li>{@link #METADATA_KEY_DISPLAY_SUBTITLE}</li> - * <li>{@link #METADATA_KEY_DISPLAY_DESCRIPTION}</li> - * <li>{@link #METADATA_KEY_DISPLAY_ICON_URI}</li> - * </ul> - * - * @param key The key for referencing this value - * @param value The String value to store - * @return The Builder to allow chaining - */ - public @NonNull Builder putString(@NonNull @TextKey String key, - @Nullable String value) { - return mProvider.putString_impl(key, value); - } - - /** - * Put a long value into the metadata. Custom keys may be used, but if - * the METADATA_KEYs defined in this class are used they may only be one - * of the following: - * <ul> - * <li>{@link #METADATA_KEY_DURATION}</li> - * <li>{@link #METADATA_KEY_TRACK_NUMBER}</li> - * <li>{@link #METADATA_KEY_NUM_TRACKS}</li> - * <li>{@link #METADATA_KEY_DISC_NUMBER}</li> - * <li>{@link #METADATA_KEY_YEAR}</li> - * <li>{@link #METADATA_KEY_BT_FOLDER_TYPE}</li> - * <li>{@link #METADATA_KEY_ADVERTISEMENT}</li> - * <li>{@link #METADATA_KEY_DOWNLOAD_STATUS}</li> - * </ul> - * - * @param key The key for referencing this value - * @param value The String value to store - * @return The Builder to allow chaining - */ - public @NonNull Builder putLong(@NonNull @LongKey String key, long value) { - return mProvider.putLong_impl(key, value); - } - - /** - * Put a {@link Rating2} into the metadata. Custom keys may be used, but - * if the METADATA_KEYs defined in this class are used they may only be - * one of the following: - * <ul> - * <li>{@link #METADATA_KEY_RATING}</li> - * <li>{@link #METADATA_KEY_USER_RATING}</li> - * </ul> - * - * @param key The key for referencing this value - * @param value The String value to store - * @return The Builder to allow chaining - */ - public @NonNull Builder putRating(@NonNull @RatingKey String key, @Nullable Rating2 value) { - return mProvider.putRating_impl(key, value); - } - - /** - * Put a {@link Bitmap} into the metadata. Custom keys may be used, but - * if the METADATA_KEYs defined in this class are used they may only be - * one of the following: - * <ul> - * <li>{@link #METADATA_KEY_ART}</li> - * <li>{@link #METADATA_KEY_ALBUM_ART}</li> - * <li>{@link #METADATA_KEY_DISPLAY_ICON}</li> - * </ul> - * Large bitmaps may be scaled down by the system when - * {@link android.media.session.MediaSession#setMetadata} is called. - * To pass full resolution images {@link Uri Uris} should be used with - * {@link #putString}. - * - * @param key The key for referencing this value - * @param value The Bitmap to store - * @return The Builder to allow chaining - */ - public @NonNull Builder putBitmap(@NonNull @BitmapKey String key, @Nullable Bitmap value) { - return mProvider.putBitmap_impl(key, value); - } - - /** - * Put a float value into the metadata. Custom keys may be used. - * - * @param key The key for referencing this value - * @param value The float value to store - * @return The Builder to allow chaining - */ - public @NonNull Builder putFloat(@NonNull @LongKey String key, float value) { - return mProvider.putFloat_impl(key, value); - } - - /** - * Set a bundle of extras. - * - * @param extras The extras to include with this description or null. - * @return The Builder to allow chaining - */ - public Builder setExtras(@Nullable Bundle extras) { - return mProvider.setExtras_impl(extras); - } - - /** - * Creates a {@link MediaMetadata2} instance with the specified fields. - * - * @return The new MediaMetadata2 instance - */ - public @NonNull MediaMetadata2 build() { - return mProvider.build_impl(); - } - } -} - diff --git a/media/java/android/media/MediaPlaylistAgent.java b/media/java/android/media/MediaPlaylistAgent.java deleted file mode 100644 index 88f37e72b621..000000000000 --- a/media/java/android/media/MediaPlaylistAgent.java +++ /dev/null @@ -1,357 +0,0 @@ -/* - * 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 android.media; - -import android.annotation.CallbackExecutor; -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.media.update.ApiLoader; -import android.media.update.MediaPlaylistAgentProvider; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.List; -import java.util.concurrent.Executor; - -/** - * @hide - * MediaPlaylistAgent is the abstract class an application needs to derive from to pass an object - * to a MediaSession2 that will override default playlist handling behaviors. It contains a set of - * notify methods to signal MediaSession2 that playlist-related state has changed. - * <p> - * Playlists are composed of one or multiple {@link MediaItem2} instances, which combine metadata - * and data sources (as {@link DataSourceDesc}) - * Used by {@link MediaSession2} and {@link MediaController2}. - */ -// This class only includes methods that contain {@link MediaItem2}. -public abstract class MediaPlaylistAgent { - /** - * @hide - */ - @IntDef({REPEAT_MODE_NONE, REPEAT_MODE_ONE, REPEAT_MODE_ALL, - REPEAT_MODE_GROUP}) - @Retention(RetentionPolicy.SOURCE) - public @interface RepeatMode {} - - /** - * Playback will be stopped at the end of the playing media list. - */ - public static final int REPEAT_MODE_NONE = 0; - - /** - * Playback of the current playing media item will be repeated. - */ - public static final int REPEAT_MODE_ONE = 1; - - /** - * Playing media list will be repeated. - */ - public static final int REPEAT_MODE_ALL = 2; - - /** - * Playback of the playing media group will be repeated. - * A group is a logical block of media items which is specified in the section 5.7 of the - * Bluetooth AVRCP 1.6. An example of a group is the playlist. - */ - public static final int REPEAT_MODE_GROUP = 3; - - /** - * @hide - */ - @IntDef({SHUFFLE_MODE_NONE, SHUFFLE_MODE_ALL, SHUFFLE_MODE_GROUP}) - @Retention(RetentionPolicy.SOURCE) - public @interface ShuffleMode {} - - /** - * Media list will be played in order. - */ - public static final int SHUFFLE_MODE_NONE = 0; - - /** - * Media list will be played in shuffled order. - */ - public static final int SHUFFLE_MODE_ALL = 1; - - /** - * Media group will be played in shuffled order. - * A group is a logical block of media items which is specified in the section 5.7 of the - * Bluetooth AVRCP 1.6. An example of a group is the playlist. - */ - public static final int SHUFFLE_MODE_GROUP = 2; - - private final MediaPlaylistAgentProvider mProvider; - - /** - * A callback class to receive notifications for events on the media player. See - * {@link MediaPlaylistAgent#registerPlaylistEventCallback(Executor, PlaylistEventCallback)} - * to register this callback. - */ - public static abstract class PlaylistEventCallback { - /** - * Called when a playlist is changed. - * - * @param playlistAgent playlist agent for this event - * @param list new playlist - * @param metadata new metadata - */ - public void onPlaylistChanged(@NonNull MediaPlaylistAgent playlistAgent, - @NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata) { } - - /** - * Called when a playlist metadata is changed. - * - * @param playlistAgent playlist agent for this event - * @param metadata new metadata - */ - public void onPlaylistMetadataChanged(@NonNull MediaPlaylistAgent playlistAgent, - @Nullable MediaMetadata2 metadata) { } - - /** - * Called when the shuffle mode is changed. - * - * @param playlistAgent playlist agent for this event - * @param shuffleMode repeat mode - * @see #SHUFFLE_MODE_NONE - * @see #SHUFFLE_MODE_ALL - * @see #SHUFFLE_MODE_GROUP - */ - public void onShuffleModeChanged(@NonNull MediaPlaylistAgent playlistAgent, - @ShuffleMode int shuffleMode) { } - - /** - * Called when the repeat mode is changed. - * - * @param playlistAgent playlist agent for this event - * @param repeatMode repeat mode - * @see #REPEAT_MODE_NONE - * @see #REPEAT_MODE_ONE - * @see #REPEAT_MODE_ALL - * @see #REPEAT_MODE_GROUP - */ - public void onRepeatModeChanged(@NonNull MediaPlaylistAgent playlistAgent, - @RepeatMode int repeatMode) { } - } - - public MediaPlaylistAgent() { - mProvider = ApiLoader.getProvider().createMediaPlaylistAgent(this); - } - - /** - * Register {@link PlaylistEventCallback} to listen changes in the underlying - * {@link MediaPlaylistAgent}. - * - * @param executor a callback Executor - * @param callback a PlaylistEventCallback - * @throws IllegalArgumentException if executor or callback is {@code null}. - */ - public final void registerPlaylistEventCallback( - @NonNull @CallbackExecutor Executor executor, @NonNull PlaylistEventCallback callback) { - mProvider.registerPlaylistEventCallback_impl(executor, callback); - } - - /** - * Unregister the previously registered {@link PlaylistEventCallback}. - * - * @param callback the callback to be removed - * @throws IllegalArgumentException if the callback is {@code null}. - */ - public final void unregisterPlaylistEventCallback(@NonNull PlaylistEventCallback callback) { - mProvider.unregisterPlaylistEventCallback_impl(callback); - } - - public final void notifyPlaylistChanged() { - mProvider.notifyPlaylistChanged_impl(); - } - - public final void notifyPlaylistMetadataChanged() { - mProvider.notifyPlaylistMetadataChanged_impl(); - } - - public final void notifyShuffleModeChanged() { - mProvider.notifyShuffleModeChanged_impl(); - } - - public final void notifyRepeatModeChanged() { - mProvider.notifyRepeatModeChanged_impl(); - } - - /** - * Returns the playlist - * - * @return playlist, or null if none is set. - */ - public @Nullable List<MediaItem2> getPlaylist() { - return mProvider.getPlaylist_impl(); - } - - /** - * Sets the playlist. - * - * @param list playlist - * @param metadata metadata of the playlist - */ - public void setPlaylist(@NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata) { - mProvider.setPlaylist_impl(list, metadata); - } - - /** - * Returns the playlist metadata - * - * @return metadata metadata of the playlist, or null if none is set - */ - public @Nullable MediaMetadata2 getPlaylistMetadata() { - return mProvider.getPlaylistMetadata_impl(); - } - - /** - * Updates the playlist metadata - * - * @param metadata metadata of the playlist - */ - public void updatePlaylistMetadata(@Nullable MediaMetadata2 metadata) { - mProvider.updatePlaylistMetadata_impl(metadata); - } - - /** - * 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 from the playlist - * - * @param item media item to remove - */ - public void removePlaylistItem(@NonNull MediaItem2 item) { - mProvider.removePlaylistItem_impl(item); - } - - /** - * 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); - } - - /** - * Skips to the the media item, and plays from it. - * - * @param item media item to start playing from - */ - public void skipToPlaylistItem(@NonNull MediaItem2 item) { - mProvider.skipToPlaylistItem_impl(item); - } - - /** - * Skips to the previous item in the playlist. - */ - public void skipToPreviousItem() { - mProvider.skipToPreviousItem_impl(); - } - - /** - * Skips to the next item in the playlist. - */ - public void skipToNextItem() { - mProvider.skipToNextItem_impl(); - } - - /** - * Gets the repeat mode - * - * @return repeat mode - * @see #REPEAT_MODE_NONE - * @see #REPEAT_MODE_ONE - * @see #REPEAT_MODE_ALL - * @see #REPEAT_MODE_GROUP - */ - public @RepeatMode int getRepeatMode() { - return mProvider.getRepeatMode_impl(); - } - - /** - * Sets the repeat mode - * - * @param repeatMode repeat mode - * @see #REPEAT_MODE_NONE - * @see #REPEAT_MODE_ONE - * @see #REPEAT_MODE_ALL - * @see #REPEAT_MODE_GROUP - */ - public void setRepeatMode(@RepeatMode int repeatMode) { - mProvider.setRepeatMode_impl(repeatMode); - } - - /** - * Gets the shuffle mode - * - * @return The shuffle mode - * @see #SHUFFLE_MODE_NONE - * @see #SHUFFLE_MODE_ALL - * @see #SHUFFLE_MODE_GROUP - */ - public @ShuffleMode int getShuffleMode() { - return mProvider.getShuffleMode_impl(); - } - - /** - * Sets the shuffle mode - * - * @param shuffleMode The shuffle mode - * @see #SHUFFLE_MODE_NONE - * @see #SHUFFLE_MODE_ALL - * @see #SHUFFLE_MODE_GROUP - */ - public void setShuffleMode(@ShuffleMode int shuffleMode) { - mProvider.setShuffleMode_impl(shuffleMode); - } - - /** - * Called by {@link MediaSession2} when it wants to translate {@link DataSourceDesc} from the - * {@link MediaPlayerBase.PlayerEventCallback} to the {@link MediaItem2}. Override this method - * if you want to create {@link DataSourceDesc}s dynamically, instead of specifying them with - * {@link #setPlaylist(List, MediaMetadata2)}. - * <p> - * Session would throw an exception if this returns {@code null} for {@param dsd} from the - * {@link MediaPlayerBase.PlayerEventCallback}. - * <p> - * Default implementation calls the {@link #getPlaylist()} and searches the {@link MediaItem2} - * with the {@param dsd}. - * - * @param dsd The dsd to query. - * @return A {@link MediaItem2} object in the playlist that matches given {@code dsd}. - * @throws IllegalArgumentException if {@code dsd} is null - */ - public @Nullable MediaItem2 getMediaItem(@NonNull DataSourceDesc dsd) { - return mProvider.getMediaItem_impl(dsd); - } -} diff --git a/media/java/android/media/MediaSession2.java b/media/java/android/media/MediaSession2.java deleted file mode 100644 index 9e97125ab072..000000000000 --- a/media/java/android/media/MediaSession2.java +++ /dev/null @@ -1,1388 +0,0 @@ -/* - * 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 android.media; - -import static android.media.MediaPlayerBase.BUFFERING_STATE_UNKNOWN; - -import android.annotation.CallbackExecutor; -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.media.MediaPlayerBase.BuffState; -import android.media.MediaPlayerBase.PlayerState; -import android.media.MediaPlaylistAgent.RepeatMode; -import android.media.MediaPlaylistAgent.ShuffleMode; -import android.media.update.ApiLoader; -import android.media.update.MediaSession2Provider; -import android.media.update.MediaSession2Provider.BuilderBaseProvider; -import android.media.update.MediaSession2Provider.CommandButtonProvider; -import android.media.update.MediaSession2Provider.ControllerInfoProvider; -import android.media.update.ProviderCreator; -import android.net.Uri; -import android.os.Bundle; -import android.os.IInterface; -import android.os.ResultReceiver; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.util.List; -import java.util.concurrent.Executor; - -/** - * @hide - * Allows a media app to expose its transport controls and playback information in a process to - * other processes including the Android framework and other apps. Common use cases are as follows. - * <ul> - * <li>Bluetooth/wired headset key events support</li> - * <li>Android Auto/Wearable support</li> - * <li>Separating UI process and playback process</li> - * </ul> - * <p> - * A MediaSession2 should be created when an app wants to publish media playback information or - * handle media keys. In general an app only needs one session for all playback, though multiple - * sessions can be created to provide finer grain controls of media. - * <p> - * A session can be obtained by {@link Builder}. The owner of the session may pass its session token - * to other processes to allow them to create a {@link MediaController2} to interact with the - * session. - * <p> - * When a session receive transport control commands, the session sends the commands directly to - * the the underlying media player set by {@link Builder} or - * {@link #updatePlayer}. - * <p> - * When an app is finished performing playback it must call {@link #close()} to clean up the session - * and notify any controllers. - * <p> - * {@link MediaSession2} objects should be used on the thread on the looper. - */ -public class MediaSession2 implements AutoCloseable { - private final MediaSession2Provider mProvider; - - /** - * @hide - */ - @IntDef({ERROR_CODE_UNKNOWN_ERROR, ERROR_CODE_APP_ERROR, ERROR_CODE_NOT_SUPPORTED, - ERROR_CODE_AUTHENTICATION_EXPIRED, ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED, - ERROR_CODE_CONCURRENT_STREAM_LIMIT, ERROR_CODE_PARENTAL_CONTROL_RESTRICTED, - ERROR_CODE_NOT_AVAILABLE_IN_REGION, ERROR_CODE_CONTENT_ALREADY_PLAYING, - ERROR_CODE_SKIP_LIMIT_REACHED, ERROR_CODE_ACTION_ABORTED, ERROR_CODE_END_OF_QUEUE, - ERROR_CODE_SETUP_REQUIRED}) - @Retention(RetentionPolicy.SOURCE) - public @interface ErrorCode {} - - /** - * This is the default error code and indicates that none of the other error codes applies. - */ - public static final int ERROR_CODE_UNKNOWN_ERROR = 0; - - /** - * Error code when the application state is invalid to fulfill the request. - */ - public static final int ERROR_CODE_APP_ERROR = 1; - - /** - * Error code when the request is not supported by the application. - */ - public static final int ERROR_CODE_NOT_SUPPORTED = 2; - - /** - * Error code when the request cannot be performed because authentication has expired. - */ - public static final int ERROR_CODE_AUTHENTICATION_EXPIRED = 3; - - /** - * Error code when a premium account is required for the request to succeed. - */ - public static final int ERROR_CODE_PREMIUM_ACCOUNT_REQUIRED = 4; - - /** - * Error code when too many concurrent streams are detected. - */ - public static final int ERROR_CODE_CONCURRENT_STREAM_LIMIT = 5; - - /** - * Error code when the content is blocked due to parental controls. - */ - public static final int ERROR_CODE_PARENTAL_CONTROL_RESTRICTED = 6; - - /** - * Error code when the content is blocked due to being regionally unavailable. - */ - public static final int ERROR_CODE_NOT_AVAILABLE_IN_REGION = 7; - - /** - * Error code when the requested content is already playing. - */ - public static final int ERROR_CODE_CONTENT_ALREADY_PLAYING = 8; - - /** - * Error code when the application cannot skip any more songs because skip limit is reached. - */ - public static final int ERROR_CODE_SKIP_LIMIT_REACHED = 9; - - /** - * Error code when the action is interrupted due to some external event. - */ - public static final int ERROR_CODE_ACTION_ABORTED = 10; - - /** - * Error code when the playback navigation (previous, next) is not possible because the queue - * was exhausted. - */ - public static final int ERROR_CODE_END_OF_QUEUE = 11; - - /** - * Error code when the session needs user's manual intervention. - */ - public static final int ERROR_CODE_SETUP_REQUIRED = 12; - - /** - * Interface definition of a callback to be invoked when a {@link MediaItem2} in the playlist - * didn't have a {@link DataSourceDesc} but it's needed now for preparing or playing it. - * - * #see #setOnDataSourceMissingHelper - */ - public interface OnDataSourceMissingHelper { - /** - * Called when a {@link MediaItem2} in the playlist didn't have a {@link DataSourceDesc} - * but it's needed now for preparing or playing it. Returned data source descriptor will be - * sent to the player directly to prepare or play the contents. - * <p> - * An exception may be thrown if the returned {@link DataSourceDesc} is duplicated in the - * playlist, so items cannot be differentiated. - * - * @param session the session for this event - * @param item media item from the controller - * @return a data source descriptor if the media item. Can be {@code null} if the content - * isn't available. - */ - @Nullable DataSourceDesc onDataSourceMissing(@NonNull MediaSession2 session, - @NonNull MediaItem2 item); - } - - /** - * Callback to be called for all incoming commands from {@link MediaController2}s. - * <p> - * If it's not set, the session will accept all controllers and all incoming commands by - * default. - */ - // TODO(jaewan): Move this to updatable for default implementation (b/74091963) - public static abstract class SessionCallback { - /** - * Called when a controller is created for this session. Return allowed commands for - * controller. By default it allows all connection requests and commands. - * <p> - * You can reject the connection by return {@code null}. In that case, controller receives - * {@link MediaController2.ControllerCallback#onDisconnected(MediaController2)} and cannot - * be usable. - * - * @param session the session for this event - * @param controller controller information. - * @return allowed commands. Can be {@code null} to reject connection. - */ - public @Nullable SessionCommandGroup2 onConnect(@NonNull MediaSession2 session, - @NonNull ControllerInfo controller) { - SessionCommandGroup2 commands = new SessionCommandGroup2(); - commands.addAllPredefinedCommands(); - return commands; - } - - /** - * Called when a controller is disconnected - * - * @param session the session for this event - * @param controller controller information - */ - public void onDisconnected(@NonNull MediaSession2 session, - @NonNull ControllerInfo controller) { } - - /** - * Called when a controller sent a command that will be sent directly to the player. Return - * {@code false} here to reject the request and stop sending command to the player. - * - * @param session the session for this event - * @param controller controller information. - * @param command a command. This method will be called for every single command. - * @return {@code true} if you want to accept incoming command. {@code false} otherwise. - * @see SessionCommand2#COMMAND_CODE_PLAYBACK_PLAY - * @see SessionCommand2#COMMAND_CODE_PLAYBACK_PAUSE - * @see SessionCommand2#COMMAND_CODE_PLAYBACK_STOP - * @see SessionCommand2#COMMAND_CODE_PLAYLIST_SKIP_NEXT_ITEM - * @see SessionCommand2#COMMAND_CODE_PLAYLIST_SKIP_PREV_ITEM - * @see SessionCommand2#COMMAND_CODE_PLAYBACK_PREPARE - * @see SessionCommand2#COMMAND_CODE_SESSION_FAST_FORWARD - * @see SessionCommand2#COMMAND_CODE_SESSION_REWIND - * @see SessionCommand2#COMMAND_CODE_PLAYBACK_SEEK_TO - * @see SessionCommand2#COMMAND_CODE_PLAYLIST_SKIP_TO_PLAYLIST_ITEM - * @see SessionCommand2#COMMAND_CODE_PLAYLIST_ADD_ITEM - * @see SessionCommand2#COMMAND_CODE_PLAYLIST_REMOVE_ITEM - * @see SessionCommand2#COMMAND_CODE_PLAYLIST_GET_LIST - * @see SessionCommand2#COMMAND_CODE_SET_VOLUME - */ - public boolean onCommandRequest(@NonNull MediaSession2 session, - @NonNull ControllerInfo controller, @NonNull SessionCommand2 command) { - return true; - } - - /** - * Called when a controller set rating of a media item through - * {@link MediaController2#setRating(String, Rating2)}. - * <p> - * To allow setting user rating for a {@link MediaItem2}, the media item's metadata - * should have {@link Rating2} with the key {@link MediaMetadata#METADATA_KEY_USER_RATING}, - * in order to provide possible rating style for controller. Controller will follow the - * rating style. - * - * @param session the session for this event - * @param controller controller information - * @param mediaId media id from the controller - * @param rating new rating from the controller - */ - public void onSetRating(@NonNull MediaSession2 session, @NonNull ControllerInfo controller, - @NonNull String mediaId, @NonNull Rating2 rating) { } - - /** - * Called when a controller sent a custom command through - * {@link MediaController2#sendCustomCommand(SessionCommand2, Bundle, ResultReceiver)}. - * - * @param session the session for this event - * @param controller controller information - * @param customCommand custom command. - * @param args optional arguments - * @param cb optional result receiver - */ - public void onCustomCommand(@NonNull MediaSession2 session, - @NonNull ControllerInfo controller, @NonNull SessionCommand2 customCommand, - @Nullable Bundle args, @Nullable ResultReceiver cb) { } - - /** - * Called when a controller requested to play a specific mediaId through - * {@link MediaController2#playFromMediaId(String, Bundle)}. - * - * @param session the session for this event - * @param controller controller information - * @param mediaId media id - * @param extras optional extra bundle - * @see SessionCommand2#COMMAND_CODE_SESSION_PLAY_FROM_MEDIA_ID - */ - public void onPlayFromMediaId(@NonNull MediaSession2 session, - @NonNull ControllerInfo controller, @NonNull String mediaId, - @Nullable Bundle extras) { } - - /** - * Called when a controller requested to begin playback from a search query through - * {@link MediaController2#playFromSearch(String, Bundle)} - * <p> - * An empty query indicates that the app may play any music. The implementation should - * attempt to make a smart choice about what to play. - * - * @param session the session for this event - * @param controller controller information - * @param query query string. Can be empty to indicate any suggested media - * @param extras optional extra bundle - * @see SessionCommand2#COMMAND_CODE_SESSION_PLAY_FROM_SEARCH - */ - public void onPlayFromSearch(@NonNull MediaSession2 session, - @NonNull ControllerInfo controller, @NonNull String query, - @Nullable Bundle extras) { } - - /** - * Called when a controller requested to play a specific media item represented by a URI - * through {@link MediaController2#playFromUri(Uri, Bundle)} - * - * @param session the session for this event - * @param controller controller information - * @param uri uri - * @param extras optional extra bundle - * @see SessionCommand2#COMMAND_CODE_SESSION_PLAY_FROM_URI - */ - public void onPlayFromUri(@NonNull MediaSession2 session, - @NonNull ControllerInfo controller, @NonNull Uri uri, - @Nullable Bundle extras) { } - - /** - * Called when a controller requested to prepare for playing a specific mediaId through - * {@link MediaController2#prepareFromMediaId(String, Bundle)}. - * <p> - * During the preparation, a session should not hold audio focus in order to allow other - * sessions play seamlessly. The state of playback should be updated to - * {@link MediaPlayerBase#PLAYER_STATE_PAUSED} after the preparation is done. - * <p> - * The playback of the prepared content should start in the later calls of - * {@link MediaSession2#play()}. - * <p> - * Override {@link #onPlayFromMediaId} to handle requests for starting - * playback without preparation. - * - * @param session the session for this event - * @param controller controller information - * @param mediaId media id to prepare - * @param extras optional extra bundle - * @see SessionCommand2#COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID - */ - public void onPrepareFromMediaId(@NonNull MediaSession2 session, - @NonNull ControllerInfo controller, @NonNull String mediaId, - @Nullable Bundle extras) { } - - /** - * Called when a controller requested to prepare playback from a search query through - * {@link MediaController2#prepareFromSearch(String, Bundle)}. - * <p> - * An empty query indicates that the app may prepare any music. The implementation should - * attempt to make a smart choice about what to play. - * <p> - * The state of playback should be updated to {@link MediaPlayerBase#PLAYER_STATE_PAUSED} - * after the preparation is done. The playback of the prepared content should start in the - * later calls of {@link MediaSession2#play()}. - * <p> - * Override {@link #onPlayFromSearch} to handle requests for starting playback without - * preparation. - * - * @param session the session for this event - * @param controller controller information - * @param query query string. Can be empty to indicate any suggested media - * @param extras optional extra bundle - * @see SessionCommand2#COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH - */ - public void onPrepareFromSearch(@NonNull MediaSession2 session, - @NonNull ControllerInfo controller, @NonNull String query, - @Nullable Bundle extras) { } - - /** - * Called when a controller requested to prepare a specific media item represented by a URI - * through {@link MediaController2#prepareFromUri(Uri, Bundle)}. - * <p> - * During the preparation, a session should not hold audio focus in order to allow - * other sessions play seamlessly. The state of playback should be updated to - * {@link MediaPlayerBase#PLAYER_STATE_PAUSED} after the preparation is done. - * <p> - * The playback of the prepared content should start in the later calls of - * {@link MediaSession2#play()}. - * <p> - * Override {@link #onPlayFromUri} to handle requests for starting playback without - * preparation. - * - * @param session the session for this event - * @param controller controller information - * @param uri uri - * @param extras optional extra bundle - * @see SessionCommand2#COMMAND_CODE_SESSION_PREPARE_FROM_URI - */ - public void onPrepareFromUri(@NonNull MediaSession2 session, - @NonNull ControllerInfo controller, @NonNull Uri uri, @Nullable Bundle extras) { } - - /** - * Called when a controller called {@link MediaController2#fastForward()} - * - * @param session the session for this event - */ - public void onFastForward(@NonNull MediaSession2 session) { } - - /** - * Called when a controller called {@link MediaController2#rewind()} - * - * @param session the session for this event - */ - public void onRewind(@NonNull MediaSession2 session) { } - - /** - * Called when the player's current playing item is changed - * <p> - * When it's called, you should invalidate previous playback information and wait for later - * callbacks. - * - * @param session the controller for this event - * @param player the player for this event - * @param item new item - */ - // TODO(jaewan): Use this (b/74316764) - public void onCurrentMediaItemChanged(@NonNull MediaSession2 session, - @NonNull MediaPlayerBase player, @NonNull MediaItem2 item) { } - - /** - * Called when the player is <i>prepared</i>, i.e. it is ready to play the content - * referenced by the given data source. - * @param session the session for this event - * @param player the player for this event - * @param item the media item for which buffering is happening - */ - public void onMediaPrepared(@NonNull MediaSession2 session, @NonNull MediaPlayerBase player, - @NonNull MediaItem2 item) { } - - /** - * Called to indicate that the state of the player has changed. - * See {@link MediaPlayerBase#getPlayerState()} for polling the player state. - * @param session the session for this event - * @param player the player for this event - * @param state the new state of the player. - */ - public void onPlayerStateChanged(@NonNull MediaSession2 session, - @NonNull MediaPlayerBase player, @PlayerState int state) { } - - /** - * Called to report buffering events for a data source. - * - * @param session the session for this event - * @param player the player for this event - * @param item the media item for which buffering is happening. - * @param state the new buffering state. - */ - public void onBufferingStateChanged(@NonNull MediaSession2 session, - @NonNull MediaPlayerBase player, @NonNull MediaItem2 item, @BuffState int state) { } - - /** - * Called to indicate that the playback speed has changed. - * @param session the session for this event - * @param player the player for this event - * @param speed the new playback speed. - */ - public void onPlaybackSpeedChanged(@NonNull MediaSession2 session, - @NonNull MediaPlayerBase player, float speed) { } - - /** - * Called to indicate that {@link #seekTo(long)} is completed. - * - * @param session the session for this event. - * @param mpb the player that has completed seeking. - * @param position the previous seeking request. - * @see #seekTo(long) - */ - public void onSeekCompleted(@NonNull MediaSession2 session, @NonNull MediaPlayerBase mpb, - long position) { } - - /** - * Called when a playlist is changed from the {@link MediaPlaylistAgent}. - * <p> - * This is called when the underlying agent has called - * {@link MediaPlaylistAgent.PlaylistEventCallback#onPlaylistChanged(MediaPlaylistAgent, - * List, MediaMetadata2)}. - * - * @param session the session for this event - * @param playlistAgent playlist agent for this event - * @param list new playlist - * @param metadata new metadata - */ - public void onPlaylistChanged(@NonNull MediaSession2 session, - @NonNull MediaPlaylistAgent playlistAgent, @NonNull List<MediaItem2> list, - @Nullable MediaMetadata2 metadata) { } - - /** - * Called when a playlist metadata is changed. - * - * @param session the session for this event - * @param playlistAgent playlist agent for this event - * @param metadata new metadata - */ - public void onPlaylistMetadataChanged(@NonNull MediaSession2 session, - @NonNull MediaPlaylistAgent playlistAgent, @Nullable MediaMetadata2 metadata) { } - - /** - * Called when the shuffle mode is changed. - * - * @param session the session for this event - * @param playlistAgent playlist agent 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 MediaSession2 session, - @NonNull MediaPlaylistAgent playlistAgent, - @MediaPlaylistAgent.ShuffleMode int shuffleMode) { } - - /** - * Called when the repeat mode is changed. - * - * @param session the session for this event - * @param playlistAgent playlist agent 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 onRepeatModeChanged(@NonNull MediaSession2 session, - @NonNull MediaPlaylistAgent playlistAgent, - @MediaPlaylistAgent.RepeatMode int repeatMode) { } - } - - /** - * Base builder class for MediaSession2 and its subclass. Any change in this class should be - * also applied to the subclasses {@link MediaSession2.Builder} and - * {@link MediaLibraryService2.MediaLibrarySession.Builder}. - * <p> - * APIs here should be package private, but should have documentations for developers. - * Otherwise, javadoc will generate documentation with the generic types such as follows. - * <pre>U extends BuilderBase<T, U, C> setSessionCallback(Executor executor, C callback)</pre> - * <p> - * This class is hidden to prevent from generating test stub, which fails with - * 'unexpected bound' because it tries to auto generate stub class as follows. - * <pre>abstract static class BuilderBase< - * T extends android.media.MediaSession2, - * U extends android.media.MediaSession2.BuilderBase< - * T, U, C extends android.media.MediaSession2.SessionCallback>, C></pre> - * @hide - */ - static abstract class BuilderBase - <T extends MediaSession2, U extends BuilderBase<T, U, C>, C extends SessionCallback> { - private final BuilderBaseProvider<T, C> mProvider; - - BuilderBase(ProviderCreator<BuilderBase<T, U, C>, BuilderBaseProvider<T, C>> creator) { - mProvider = creator.createProvider(this); - } - - /** - * Sets the underlying {@link MediaPlayerBase} for this session to dispatch incoming event - * to. - * - * @param player a {@link MediaPlayerBase} that handles actual media playback in your app. - */ - @NonNull U setPlayer(@NonNull MediaPlayerBase player) { - mProvider.setPlayer_impl(player); - return (U) this; - } - - /** - * Sets the {@link MediaPlaylistAgent} for this session to manages playlist of the - * underlying {@link MediaPlayerBase}. The playlist agent should manage - * {@link MediaPlayerBase} for calling {@link MediaPlayerBase#setNextDataSources(List)}. - * <p> - * If the {@link MediaPlaylistAgent} isn't set, session will create the default playlist - * agent. - * - * @param playlistAgent a {@link MediaPlaylistAgent} that manages playlist of the - * {@code player} - */ - U setPlaylistAgent(@NonNull MediaPlaylistAgent playlistAgent) { - mProvider.setPlaylistAgent_impl(playlistAgent); - return (U) this; - } - - /** - * Sets the {@link VolumeProvider2} for this session to handle volume events. If not set, - * system will adjust the appropriate stream volume for this session's player. - * - * @param volumeProvider The provider that will receive volume button events. - */ - @NonNull U setVolumeProvider(@Nullable VolumeProvider2 volumeProvider) { - mProvider.setVolumeProvider_impl(volumeProvider); - return (U) this; - } - - /** - * Set an intent for launching UI for this Session. This can be used as a - * quick link to an ongoing media screen. The intent should be for an - * activity that may be started using {@link Context#startActivity(Intent)}. - * - * @param pi The intent to launch to show UI for this session. - */ - @NonNull U setSessionActivity(@Nullable PendingIntent pi) { - mProvider.setSessionActivity_impl(pi); - return (U) this; - } - - /** - * Set ID of the session. If it's not set, an empty string with used to create a session. - * <p> - * Use this if and only if your app supports multiple playback at the same time and also - * wants to provide external apps to have finer controls of them. - * - * @param id id of the session. Must be unique per package. - * @throws IllegalArgumentException if id is {@code null} - * @return - */ - @NonNull U setId(@NonNull String id) { - mProvider.setId_impl(id); - return (U) this; - } - - /** - * Set callback for the session. - * - * @param executor callback executor - * @param callback session callback. - * @return - */ - @NonNull U setSessionCallback(@NonNull @CallbackExecutor Executor executor, - @NonNull C callback) { - mProvider.setSessionCallback_impl(executor, callback); - return (U) this; - } - - /** - * Build {@link MediaSession2}. - * - * @return a new session - * @throws IllegalStateException if the session with the same id is already exists for the - * package. - */ - @NonNull T build() { - return mProvider.build_impl(); - } - } - - /** - * Builder for {@link MediaSession2}. - * <p> - * Any incoming event from the {@link MediaController2} will be handled on the thread - * that created session with the {@link Builder#build()}. - */ - // Override all methods just to show them with the type instead of generics in Javadoc. - // This workarounds javadoc issue described in the MediaSession2.BuilderBase. - public static final class Builder extends BuilderBase<MediaSession2, Builder, SessionCallback> { - public Builder(Context context) { - super((instance) -> ApiLoader.getProvider().createMediaSession2Builder( - context, (Builder) instance)); - } - - @Override - public @NonNull Builder setPlayer(@NonNull MediaPlayerBase player) { - return super.setPlayer(player); - } - - @Override - public Builder setPlaylistAgent(@NonNull MediaPlaylistAgent playlistAgent) { - return super.setPlaylistAgent(playlistAgent); - } - - @Override - public @NonNull Builder setVolumeProvider(@Nullable VolumeProvider2 volumeProvider) { - return super.setVolumeProvider(volumeProvider); - } - - @Override - public @NonNull Builder setSessionActivity(@Nullable PendingIntent pi) { - return super.setSessionActivity(pi); - } - - @Override - public @NonNull Builder setId(@NonNull String id) { - return super.setId(id); - } - - @Override - public @NonNull Builder setSessionCallback(@NonNull Executor executor, - @Nullable SessionCallback callback) { - return super.setSessionCallback(executor, callback); - } - - @Override - public @NonNull MediaSession2 build() { - return super.build(); - } - } - - /** - * Information of a controller. - */ - public static final class ControllerInfo { - private final ControllerInfoProvider mProvider; - - /** - * @hide - */ - public ControllerInfo(@NonNull Context context, int uid, int pid, - @NonNull String packageName, @NonNull IInterface callback) { - mProvider = ApiLoader.getProvider().createMediaSession2ControllerInfo( - context, this, uid, pid, packageName, callback); - } - - /** - * @return package name of the controller - */ - public @NonNull String getPackageName() { - return mProvider.getPackageName_impl(); - } - - /** - * @return uid of the controller - */ - public int getUid() { - return mProvider.getUid_impl(); - } - - /** - * Return if the controller has granted {@code android.permission.MEDIA_CONTENT_CONTROL} or - * has a enabled notification listener so can be trusted to accept connection and incoming - * command request. - * - * @return {@code true} if the controller is trusted. - */ - public boolean isTrusted() { - return mProvider.isTrusted_impl(); - } - - /** - * @hide - */ - public @NonNull ControllerInfoProvider getProvider() { - return mProvider; - } - - @Override - public int hashCode() { - return mProvider.hashCode_impl(); - } - - @Override - public boolean equals(Object obj) { - return mProvider.equals_impl(obj); - } - - @Override - public String toString() { - return mProvider.toString_impl(); - } - } - - /** - * Button for a {@link SessionCommand2} that will be shown by the controller. - * <p> - * It's up to the controller's decision to respect or ignore this customization request. - */ - public static final class CommandButton { - private final CommandButtonProvider mProvider; - - /** - * @hide - */ - public CommandButton(CommandButtonProvider provider) { - mProvider = provider; - } - - /** - * Get command associated with this button. Can be {@code null} if the button isn't enabled - * and only providing placeholder. - * - * @return command or {@code null} - */ - public @Nullable - SessionCommand2 getCommand() { - return mProvider.getCommand_impl(); - } - - /** - * Resource id of the button in this package. Can be {@code 0} if the command is predefined - * and custom icon isn't needed. - * - * @return resource id of the icon. Can be {@code 0}. - */ - public int getIconResId() { - return mProvider.getIconResId_impl(); - } - - /** - * Display name of the button. Can be {@code null} or empty if the command is predefined - * and custom name isn't needed. - * - * @return custom display name. Can be {@code null} or empty. - */ - public @Nullable String getDisplayName() { - return mProvider.getDisplayName_impl(); - } - - /** - * Extra information of the button. It's private information between session and controller. - * - * @return - */ - public @Nullable Bundle getExtras() { - return mProvider.getExtras_impl(); - } - - /** - * Return whether it's enabled - * - * @return {@code true} if enabled. {@code false} otherwise. - */ - public boolean isEnabled() { - return mProvider.isEnabled_impl(); - } - - /** - * @hide - */ - public @NonNull CommandButtonProvider getProvider() { - return mProvider; - } - - /** - * Builder for {@link CommandButton}. - */ - public static final class Builder { - private final CommandButtonProvider.BuilderProvider mProvider; - - public Builder() { - mProvider = ApiLoader.getProvider().createMediaSession2CommandButtonBuilder(this); - } - - public @NonNull Builder setCommand(@Nullable SessionCommand2 command) { - return mProvider.setCommand_impl(command); - } - - public @NonNull Builder setIconResId(int resId) { - return mProvider.setIconResId_impl(resId); - } - - public @NonNull Builder setDisplayName(@Nullable String displayName) { - return mProvider.setDisplayName_impl(displayName); - } - - public @NonNull Builder setEnabled(boolean enabled) { - return mProvider.setEnabled_impl(enabled); - } - - public @NonNull Builder setExtras(@Nullable Bundle extras) { - return mProvider.setExtras_impl(extras); - } - - public @NonNull CommandButton build() { - return mProvider.build_impl(); - } - } - } - - /** - * Constructor is hidden and apps can only instantiate indirectly through {@link Builder}. - * <p> - * This intended behavior and here's the reasons. - * 1. Prevent multiple sessions with the same tag in a media app. - * Whenever it happens only one session was properly setup and others were all dummies. - * Android framework couldn't find the right session to dispatch media key event. - * 2. Simplify session's lifecycle. - * {@link android.media.session.MediaSession} is available after all of - * {@link android.media.session.MediaSession#setFlags(int)}, - * {@link android.media.session.MediaSession#setCallback( - * android.media.session.MediaSession.Callback)}, - * and {@link android.media.session.MediaSession#setActive(boolean)}. - * It was common for an app to omit one, so framework had to add heuristics to figure out - * which should be the highest priority for handling media key event. - * @hide - */ - public MediaSession2(MediaSession2Provider provider) { - super(); - mProvider = provider; - } - - /** - * @hide - */ - public @NonNull MediaSession2Provider getProvider() { - return mProvider; - } - - /** - * Sets the underlying {@link MediaPlayerBase} and {@link MediaPlaylistAgent} for this session - * to dispatch incoming event to. - * <p> - * When a {@link MediaPlaylistAgent} is specified here, the playlist agent should manage - * {@link MediaPlayerBase} for calling {@link MediaPlayerBase#setNextDataSources(List)}. - * <p> - * If the {@link MediaPlaylistAgent} isn't set, session will recreate the default playlist - * agent. - * - * @param player a {@link MediaPlayerBase} that handles actual media playback in your app - * @param playlistAgent a {@link MediaPlaylistAgent} that manages playlist of the {@code player} - * @param volumeProvider a {@link VolumeProvider2}. If {@code null}, system will adjust the - * appropriate stream volume for this session's player. - */ - public void updatePlayer(@NonNull MediaPlayerBase player, - @Nullable MediaPlaylistAgent playlistAgent, @Nullable VolumeProvider2 volumeProvider) { - mProvider.updatePlayer_impl(player, playlistAgent, volumeProvider); - } - - @Override - public void close() { - mProvider.close_impl(); - } - - /** - * @return player - */ - public @NonNull MediaPlayerBase getPlayer() { - return mProvider.getPlayer_impl(); - } - - /** - * @return playlist agent - */ - public @NonNull MediaPlaylistAgent getPlaylistAgent() { - return mProvider.getPlaylistAgent_impl(); - } - - /** - * @return volume provider - */ - public @Nullable VolumeProvider2 getVolumeProvider() { - return mProvider.getVolumeProvider_impl(); - } - - /** - * Returns the {@link SessionToken2} for creating {@link MediaController2}. - */ - public @NonNull - SessionToken2 getToken() { - return mProvider.getToken_impl(); - } - - public @NonNull List<ControllerInfo> getConnectedControllers() { - return mProvider.getConnectedControllers_impl(); - } - - /** - * Set the {@link AudioFocusRequest} to obtain the audio focus - * - * @param afr the full request parameters - */ - public void setAudioFocusRequest(@Nullable AudioFocusRequest afr) { - // TODO(jaewan): implement this (b/72529899) - // mProvider.setAudioFocusRequest_impl(focusGain); - } - - /** - * Sets ordered list of {@link CommandButton} for controllers to build UI with it. - * <p> - * It's up to controller's decision how to represent the layout in its own UI. - * Here's the same way - * (layout[i] means a CommandButton at index i in the given list) - * For 5 icons row - * layout[3] layout[1] layout[0] layout[2] layout[4] - * For 3 icons row - * layout[1] layout[0] layout[2] - * For 5 icons row with overflow icon (can show +5 extra buttons with overflow button) - * expanded row: layout[5] layout[6] layout[7] layout[8] layout[9] - * main row: layout[3] layout[1] layout[0] layout[2] layout[4] - * <p> - * This API can be called in the {@link SessionCallback#onConnect( - * MediaSession2, ControllerInfo)}. - * - * @param controller controller to specify layout. - * @param layout ordered list of layout. - */ - public void setCustomLayout(@NonNull ControllerInfo controller, - @NonNull List<CommandButton> layout) { - mProvider.setCustomLayout_impl(controller, layout); - } - - /** - * Set the new allowed command group for the controller - * - * @param controller controller to change allowed commands - * @param commands new allowed commands - */ - public void setAllowedCommands(@NonNull ControllerInfo controller, - @NonNull SessionCommandGroup2 commands) { - mProvider.setAllowedCommands_impl(controller, commands); - } - - /** - * Send custom command to all connected controllers. - * - * @param command a command - * @param args optional argument - */ - public void sendCustomCommand(@NonNull SessionCommand2 command, @Nullable Bundle args) { - mProvider.sendCustomCommand_impl(command, args); - } - - /** - * Send custom command to a specific controller. - * - * @param command a command - * @param args optional argument - * @param receiver result receiver for the session - */ - public void sendCustomCommand(@NonNull ControllerInfo controller, - @NonNull SessionCommand2 command, @Nullable Bundle args, - @Nullable ResultReceiver receiver) { - // Equivalent to the MediaController.sendCustomCommand(Action action, ResultReceiver r); - mProvider.sendCustomCommand_impl(controller, command, args, receiver); - } - - /** - * Play playback - * <p> - * This calls {@link MediaPlayerBase#play()}. - */ - public void play() { - mProvider.play_impl(); - } - - /** - * Pause playback. - * <p> - * This calls {@link MediaPlayerBase#pause()}. - */ - public void pause() { - mProvider.pause_impl(); - } - - /** - * Stop playback, and reset the player to the initial state. - * <p> - * This calls {@link MediaPlayerBase#reset()}. - */ - public void stop() { - mProvider.stop_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 MediaPlayerBase#PLAYER_STATE_PAUSED}. Afterwards, {@link #play} can be called - * to start playback. - * <p> - * This calls {@link MediaPlayerBase#reset()}. - */ - public void prepare() { - mProvider.prepare_impl(); - } - - /** - * Move to a new location in the media stream. - * - * @param pos Position to move to, in milliseconds. - */ - public void seekTo(long pos) { - mProvider.seekTo_impl(pos); - } - - /** - * @hide - */ - public void skipForward() { - // To match with KEYCODE_MEDIA_SKIP_FORWARD - } - - /** - * @hide - */ - public void skipBackward() { - // To match with KEYCODE_MEDIA_SKIP_BACKWARD - } - - /** - * Notify errors to the connected controllers - * - * @param errorCode error code - * @param extras extras - */ - public void notifyError(@ErrorCode int errorCode, @Nullable Bundle extras) { - mProvider.notifyError_impl(errorCode, extras); - } - - /** - * Gets the current player state. - * - * @return the current player state - */ - public @PlayerState int getPlayerState() { - return mProvider.getPlayerState_impl(); - } - - /** - * Gets the current position. - * - * @return the current playback position in ms, or {@link MediaPlayerBase#UNKNOWN_TIME} if - * unknown. - */ - public long getCurrentPosition() { - return mProvider.getCurrentPosition_impl(); - } - - /** - * Gets the buffered position, or {@link MediaPlayerBase#UNKNOWN_TIME} if unknown. - * - * @return the buffered position in ms, or {@link MediaPlayerBase#UNKNOWN_TIME}. - */ - public long getBufferedPosition() { - return mProvider.getBufferedPosition_impl(); - } - - /** - * 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 @BuffState int getBufferingState() { - // TODO(jaewan): Implement this - return BUFFERING_STATE_UNKNOWN; - } - - /** - * Get the playback speed. - * - * @return speed - */ - public float getPlaybackSpeed() { - // TODO(jaewan): implement this (b/74093080) - return -1; - } - - /** - * Set the playback speed. - */ - public void setPlaybackSpeed(float speed) { - // TODO(jaewan): implement this (b/74093080) - } - - /** - * Sets the data source missing helper. Helper will be used to provide default implementation of - * {@link MediaPlaylistAgent} when it isn't set by developer. - * <p> - * Default implementation of the {@link MediaPlaylistAgent} will call helper when a - * {@link MediaItem2} in the playlist doesn't have a {@link DataSourceDesc}. This may happen - * when - * <ul> - * <li>{@link MediaItem2} specified by {@link #setPlaylist(List, MediaMetadata2)} doesn't - * have {@link DataSourceDesc}</li> - * <li>{@link MediaController2#addPlaylistItem(int, MediaItem2)} is called and accepted - * by {@link SessionCallback#onCommandRequest( - * MediaSession2, ControllerInfo, SessionCommand2)}. - * In that case, an item would be added automatically without the data source.</li> - * </ul> - * <p> - * If it's not set, playback wouldn't happen for the item without data source descriptor. - * <p> - * The helper will be run on the executor that was specified by - * {@link Builder#setSessionCallback(Executor, SessionCallback)}. - * - * @param helper a data source missing helper. - * @throws IllegalStateException when the helper is set when the playlist agent is set - * @see #setPlaylist(List, MediaMetadata2) - * @see SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2) - * @see SessionCommand2#COMMAND_CODE_PLAYLIST_ADD_ITEM - * @see SessionCommand2#COMMAND_CODE_PLAYLIST_REPLACE_ITEM - */ - public void setOnDataSourceMissingHelper(@NonNull OnDataSourceMissingHelper helper) { - mProvider.setOnDataSourceMissingHelper_impl(helper); - } - - /** - * Clears the data source missing helper. - * - * @see #setOnDataSourceMissingHelper(OnDataSourceMissingHelper) - */ - public void clearOnDataSourceMissingHelper() { - mProvider.clearOnDataSourceMissingHelper_impl(); - } - - /** - * Returns the playlist from the {@link MediaPlaylistAgent}. - * <p> - * This list may differ with the list that was specified with - * {@link #setPlaylist(List, MediaMetadata2)} depending on the {@link MediaPlaylistAgent} - * implementation. Use media items returned here for other playlist agent APIs such as - * {@link MediaPlaylistAgent#skipToPlaylistItem(MediaItem2)}. - * - * @return playlist - * @see MediaPlaylistAgent#getPlaylist() - * @see SessionCallback#onPlaylistChanged( - * MediaSession2, MediaPlaylistAgent, List, MediaMetadata2) - */ - public List<MediaItem2> getPlaylist() { - return mProvider.getPlaylist_impl(); - } - - /** - * Sets a list of {@link MediaItem2} to the {@link MediaPlaylistAgent}. Ensure uniqueness of - * each {@link MediaItem2} in the playlist so the session can uniquely identity individual - * items. - * <p> - * This may be an asynchronous call, and {@link MediaPlaylistAgent} may keep the copy of the - * list. Wait for {@link SessionCallback#onPlaylistChanged(MediaSession2, MediaPlaylistAgent, - * List, MediaMetadata2)} to know the operation finishes. - * <p> - * You may specify a {@link MediaItem2} without {@link DataSourceDesc}. In that case, - * {@link MediaPlaylistAgent} has responsibility to dynamically query {@link DataSourceDesc} - * when such media item is ready for preparation or play. Default implementation needs - * {@link OnDataSourceMissingHelper} for such case. - * - * @param list A list of {@link MediaItem2} objects to set as a play list. - * @throws IllegalArgumentException if given list is {@code null}, or has duplicated media - * items. - * @see MediaPlaylistAgent#setPlaylist(List, MediaMetadata2) - * @see SessionCallback#onPlaylistChanged( - * MediaSession2, MediaPlaylistAgent, List, MediaMetadata2) - * @see #setOnDataSourceMissingHelper - */ - public void setPlaylist(@NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata) { - mProvider.setPlaylist_impl(list, metadata); - } - - /** - * Skips to the item in the playlist. - * <p> - * This calls {@link MediaPlaylistAgent#skipToPlaylistItem(MediaItem2)} and the behavior depends - * on the playlist agent implementation, especially with the shuffle/repeat mode. - * - * @param item The item in the playlist you want to play - * @see #getShuffleMode() - * @see #getRepeatMode() - */ - public void skipToPlaylistItem(@NonNull MediaItem2 item) { - mProvider.skipToPlaylistItem_impl(item); - } - - /** - * Skips to the previous item. - * <p> - * This calls {@link MediaPlaylistAgent#skipToPreviousItem()} and the behavior depends on the - * playlist agent implementation, especially with the shuffle/repeat mode. - * - * @see #getShuffleMode() - * @see #getRepeatMode() - **/ - public void skipToPreviousItem() { - mProvider.skipToPreviousItem_impl(); - } - - /** - * Skips to the next item. - * <p> - * This calls {@link MediaPlaylistAgent#skipToNextItem()} and the behavior depends on the - * playlist agent implementation, especially with the shuffle/repeat mode. - * - * @see #getShuffleMode() - * @see #getRepeatMode() - */ - public void skipToNextItem() { - mProvider.skipToNextItem_impl(); - } - - /** - * Gets the playlist metadata from the {@link MediaPlaylistAgent}. - * - * @return the playlist metadata - */ - public MediaMetadata2 getPlaylistMetadata() { - return mProvider.getPlaylistMetadata_impl(); - } - - /** - * 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 play list, - * the current index of the play list 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 in the playlist. - * <p> - * 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. - * - * @param item the media item you want to add - */ - public void removePlaylistItem(@NonNull MediaItem2 item) { - mProvider.removePlaylistItem_impl(item); - } - - /** - * Replaces 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); - } - - /** - * Return currently playing media item. - * - * @return currently playing media item - */ - public MediaItem2 getCurrentMediaItem() { - // TODO(jaewan): Rename provider, and implement (b/74316764) - return mProvider.getCurrentPlaylistItem_impl(); - } - - /** - * Updates the playlist metadata to the {@link MediaPlaylistAgent}. - * - * @param metadata metadata of the playlist - */ - public void updatePlaylistMetadata(@Nullable MediaMetadata2 metadata) { - mProvider.updatePlaylistMetadata_impl(metadata); - } - - /** - * Gets the repeat mode from the {@link MediaPlaylistAgent}. - * - * @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 to the {@link MediaPlaylistAgent}. - * - * @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 shuffle mode from the {@link MediaPlaylistAgent}. - * - * @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 to the {@link MediaPlaylistAgent}. - * - * @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); - } -} diff --git a/media/java/android/media/Rating2.java b/media/java/android/media/Rating2.java deleted file mode 100644 index 9213190184ef..000000000000 --- a/media/java/android/media/Rating2.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * 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 android.media; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.annotation.IntDef; -import android.media.update.ApiLoader; -import android.media.update.Rating2Provider; -import android.os.Bundle; -import android.util.Log; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @hide - * A class to encapsulate rating information used as content metadata. - * A rating is defined by its rating style (see {@link #RATING_HEART}, - * {@link #RATING_THUMB_UP_DOWN}, {@link #RATING_3_STARS}, {@link #RATING_4_STARS}, - * {@link #RATING_5_STARS} or {@link #RATING_PERCENTAGE}) and the actual rating value (which may - * be defined as "unrated"), both of which are defined when the rating instance is constructed - * through one of the factory methods. - */ -// New version of Rating with following change -// - Don't implement Parcelable for updatable support. -public final class Rating2 { - /** - * @hide - */ - @IntDef({RATING_NONE, RATING_HEART, RATING_THUMB_UP_DOWN, RATING_3_STARS, RATING_4_STARS, - RATING_5_STARS, RATING_PERCENTAGE}) - @Retention(RetentionPolicy.SOURCE) - public @interface Style {} - - /** - * @hide - */ - @IntDef({RATING_3_STARS, RATING_4_STARS, RATING_5_STARS}) - @Retention(RetentionPolicy.SOURCE) - public @interface StarStyle {} - - /** - * Indicates a rating style is not supported. A Rating2 will never have this - * type, but can be used by other classes to indicate they do not support - * Rating2. - */ - public final static int RATING_NONE = 0; - - /** - * A rating style with a single degree of rating, "heart" vs "no heart". Can be used to - * indicate the content referred to is a favorite (or not). - */ - public final static int RATING_HEART = 1; - - /** - * A rating style for "thumb up" vs "thumb down". - */ - public final static int RATING_THUMB_UP_DOWN = 2; - - /** - * A rating style with 0 to 3 stars. - */ - public final static int RATING_3_STARS = 3; - - /** - * A rating style with 0 to 4 stars. - */ - public final static int RATING_4_STARS = 4; - - /** - * A rating style with 0 to 5 stars. - */ - public final static int RATING_5_STARS = 5; - - /** - * A rating style expressed as a percentage. - */ - public final static int RATING_PERCENTAGE = 6; - - private final Rating2Provider mProvider; - - /** - * @hide - */ - public Rating2(@NonNull Rating2Provider provider) { - mProvider = provider; - } - - @Override - public String toString() { - return mProvider.toString_impl(); - } - - /** - * @hide - */ - public Rating2Provider getProvider() { - return mProvider; - } - - @Override - public boolean equals(Object obj) { - return mProvider.equals_impl(obj); - } - - @Override - public int hashCode() { - return mProvider.hashCode_impl(); - } - - /** - * Create an instance from bundle object, previoulsy created by {@link #toBundle()} - * - * @param bundle bundle - * @return new Rating2 instance or {@code null} for error - */ - public static Rating2 fromBundle(@Nullable Bundle bundle) { - return ApiLoader.getProvider().fromBundle_Rating2(bundle); - } - - /** - * Return bundle for this object to share across the process. - * @return bundle of this object - */ - public Bundle toBundle() { - return mProvider.toBundle_impl(); - } - - /** - * Return a Rating2 instance with no rating. - * Create and return a new Rating2 instance with no rating known for the given - * rating style. - * @param ratingStyle one of {@link #RATING_HEART}, {@link #RATING_THUMB_UP_DOWN}, - * {@link #RATING_3_STARS}, {@link #RATING_4_STARS}, {@link #RATING_5_STARS}, - * or {@link #RATING_PERCENTAGE}. - * @return null if an invalid rating style is passed, a new Rating2 instance otherwise. - */ - public static @Nullable Rating2 newUnratedRating(@Style int ratingStyle) { - return ApiLoader.getProvider().newUnratedRating_Rating2(ratingStyle); - } - - /** - * Return a Rating2 instance with a heart-based rating. - * Create and return a new Rating2 instance with a rating style of {@link #RATING_HEART}, - * and a heart-based rating. - * @param hasHeart true for a "heart selected" rating, false for "heart unselected". - * @return a new Rating2 instance. - */ - public static @Nullable Rating2 newHeartRating(boolean hasHeart) { - return ApiLoader.getProvider().newHeartRating_Rating2(hasHeart); - } - - /** - * Return a Rating2 instance with a thumb-based rating. - * Create and return a new Rating2 instance with a {@link #RATING_THUMB_UP_DOWN} - * rating style, and a "thumb up" or "thumb down" rating. - * @param thumbIsUp true for a "thumb up" rating, false for "thumb down". - * @return a new Rating2 instance. - */ - public static @Nullable Rating2 newThumbRating(boolean thumbIsUp) { - return ApiLoader.getProvider().newThumbRating_Rating2(thumbIsUp); - } - - /** - * Return a Rating2 instance with a star-based rating. - * Create and return a new Rating2 instance with one of the star-base rating styles - * and the given integer or fractional number of stars. Non integer values can for instance - * be used to represent an average rating value, which might not be an integer number of stars. - * @param starRatingStyle one of {@link #RATING_3_STARS}, {@link #RATING_4_STARS}, - * {@link #RATING_5_STARS}. - * @param starRating a number ranging from 0.0f to 3.0f, 4.0f or 5.0f according to - * the rating style. - * @return null if the rating style is invalid, or the rating is out of range, - * a new Rating2 instance otherwise. - */ - public static @Nullable Rating2 newStarRating( - @StarStyle int starRatingStyle, float starRating) { - return ApiLoader.getProvider().newStarRating_Rating2(starRatingStyle, starRating); - } - - /** - * Return a Rating2 instance with a percentage-based rating. - * Create and return a new Rating2 instance with a {@link #RATING_PERCENTAGE} - * rating style, and a rating of the given percentage. - * @param percent the value of the rating - * @return null if the rating is out of range, a new Rating2 instance otherwise. - */ - public static @Nullable Rating2 newPercentageRating(float percent) { - return ApiLoader.getProvider().newPercentageRating_Rating2(percent); - } - - /** - * Return whether there is a rating value available. - * @return true if the instance was not created with {@link #newUnratedRating(int)}. - */ - public boolean isRated() { - return mProvider.isRated_impl(); - } - - /** - * Return the rating style. - * @return one of {@link #RATING_HEART}, {@link #RATING_THUMB_UP_DOWN}, - * {@link #RATING_3_STARS}, {@link #RATING_4_STARS}, {@link #RATING_5_STARS}, - * or {@link #RATING_PERCENTAGE}. - */ - public @Style int getRatingStyle() { - return mProvider.getRatingStyle_impl(); - } - - /** - * Return whether the rating is "heart selected". - * @return true if the rating is "heart selected", false if the rating is "heart unselected", - * if the rating style is not {@link #RATING_HEART} or if it is unrated. - */ - public boolean hasHeart() { - return mProvider.hasHeart_impl(); - } - - /** - * Return whether the rating is "thumb up". - * @return true if the rating is "thumb up", false if the rating is "thumb down", - * if the rating style is not {@link #RATING_THUMB_UP_DOWN} or if it is unrated. - */ - public boolean isThumbUp() { - return mProvider.isThumbUp_impl(); - } - - /** - * Return the star-based rating value. - * @return a rating value greater or equal to 0.0f, or a negative value if the rating style is - * not star-based, or if it is unrated. - */ - public float getStarRating() { - return mProvider.getStarRating_impl(); - } - - /** - * Return the percentage-based rating value. - * @return a rating value greater or equal to 0.0f, or a negative value if the rating style is - * not percentage-based, or if it is unrated. - */ - public float getPercentRating() { - return mProvider.getPercentRating_impl(); - } -} diff --git a/media/java/android/media/SessionCommand2.java b/media/java/android/media/SessionCommand2.java deleted file mode 100644 index fe86a3ae49ec..000000000000 --- a/media/java/android/media/SessionCommand2.java +++ /dev/null @@ -1,336 +0,0 @@ -/* - * 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 android.media; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.Context; -import android.media.update.ApiLoader; -import android.media.update.MediaSession2Provider; -import android.media.MediaSession2.ControllerInfo; -import android.media.MediaSession2.SessionCallback; -import android.net.Uri; -import android.os.Bundle; - -import java.util.List; - -/** - * @hide - * Define a command that a {@link MediaController2} can send to a {@link MediaSession2}. - * <p> - * If {@link #getCommandCode()} isn't {@link #COMMAND_CODE_CUSTOM}), it's predefined command. - * If {@link #getCommandCode()} is {@link #COMMAND_CODE_CUSTOM}), it's custom command and - * {@link #getCustomCommand()} shouldn't be {@code null}. - */ -public final class SessionCommand2 { - /** - * Command code for the custom command which can be defined by string action in the - * {@link SessionCommand2}. - */ - public static final int COMMAND_CODE_CUSTOM = 0; - - /** - * Command code for {@link MediaController2#play()}. - * <p> - * Command would be sent directly to the player if the session doesn't reject the request - * through the {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, - * SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYBACK_PLAY = 1; - - /** - * Command code for {@link MediaController2#pause()}. - * <p> - * Command would be sent directly to the player if the session doesn't reject the request - * through the {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, - * SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYBACK_PAUSE = 2; - - /** - * Command code for {@link MediaController2#stop()}. - * <p> - * Command would be sent directly to the player if the session doesn't reject the request - * through the {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, - * SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYBACK_STOP = 3; - - /** - * Command code for {@link MediaController2#skipToNextItem()}. - * <p> - * Command would be sent directly to the playlist agent if the session doesn't reject the - * request through the {@link SessionCallback#onCommandRequest( - * MediaSession2, ControllerInfo, SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYLIST_SKIP_NEXT_ITEM = 4; - - /** - * Command code for {@link MediaController2#skipToPreviousItem()}. - * <p> - * Command would be sent directly to the playlist agent if the session doesn't reject the - * request through the {@link SessionCallback#onCommandRequest( - * MediaSession2, ControllerInfo, SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYLIST_SKIP_PREV_ITEM = 5; - - /** - * Command code for {@link MediaController2#prepare()}. - * <p> - * Command would be sent directly to the player if the session doesn't reject the request - * through the {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, - * SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYBACK_PREPARE = 6; - - /** - * Command code for {@link MediaController2#fastForward()}. - */ - public static final int COMMAND_CODE_SESSION_FAST_FORWARD = 7; - - /** - * Command code for {@link MediaController2#rewind()}. - */ - public static final int COMMAND_CODE_SESSION_REWIND = 8; - - /** - * Command code for {@link MediaController2#seekTo(long)}. - * <p> - * Command would be sent directly to the player if the session doesn't reject the request - * through the {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, - * SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYBACK_SEEK_TO = 9; - - /** - * Command code for both {@link MediaController2#setVolumeTo(int, int)}. - * <p> - * Command would set the device volume or send to the volume provider directly if the session - * doesn't reject the request through the - * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. - */ - public static final int COMMAND_CODE_SET_VOLUME = 10; - - /** - * Command code for both {@link MediaController2#adjustVolume(int, int)}. - * <p> - * Command would adjust the device volume or send to the volume provider directly if the session - * doesn't reject the request through the - * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. - */ - public static final int COMMAND_CODE_ADJUST_VOLUME = 11; - - /** - * Command code for {@link MediaController2#skipToPlaylistItem(MediaItem2)}. - * <p> - * Command would be sent directly to the playlist agent if the session doesn't reject the - * request through the - * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYLIST_SKIP_TO_PLAYLIST_ITEM = 12; - - /** - * Command code for {@link MediaController2#setShuffleMode(int)}. - * <p> - * Command would be sent directly to the playlist agent if the session doesn't reject the - * request through the - * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYLIST_SET_SHUFFLE_MODE = 13; - - /** - * Command code for {@link MediaController2#setRepeatMode(int)}. - * <p> - * Command would be sent directly to the playlist agent if the session doesn't reject the - * request through the - * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYLIST_SET_REPEAT_MODE = 14; - - /** - * Command code for {@link MediaController2#addPlaylistItem(int, MediaItem2)}. - * <p> - * Command would be sent directly to the playlist agent if the session doesn't reject the - * request through the - * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYLIST_ADD_ITEM = 15; - - /** - * Command code for {@link MediaController2#addPlaylistItem(int, MediaItem2)}. - * <p> - * Command would be sent directly to the playlist agent if the session doesn't reject the - * request through the - * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYLIST_REMOVE_ITEM = 16; - - /** - * Command code for {@link MediaController2#replacePlaylistItem(int, MediaItem2)}. - * <p> - * Command would be sent directly to the playlist agent if the session doesn't reject the - * request through the - * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYLIST_REPLACE_ITEM = 17; - - /** - * Command code for {@link MediaController2#getPlaylist()}. This will expose metadata - * information to the controller. - * <p> - * Command would be sent directly to the playlist agent if the session doesn't reject the - * request through the - * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYLIST_GET_LIST = 18; - - /** - * Command code for {@link MediaController2#setPlaylist(List, MediaMetadata2)}. - * <p> - * Command would be sent directly to the playlist agent if the session doesn't reject the - * request through the - * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYLIST_SET_LIST = 19; - - /** - * Command code for {@link MediaController2#getPlaylistMetadata()}. This will expose - * metadata information to the controller. - * <p> - * Command would be sent directly to the playlist agent if the session doesn't reject the - * request through the - * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYLIST_GET_LIST_METADATA = 20; - - /** - * Command code for {@link MediaController2#updatePlaylistMetadata(MediaMetadata2)}. - * <p> - * Command would be sent directly to the playlist agent if the session doesn't reject the - * request through the - * {@link SessionCallback#onCommandRequest(MediaSession2, ControllerInfo, SessionCommand2)}. - */ - public static final int COMMAND_CODE_PLAYLIST_SET_LIST_METADATA = 21; - - /** - * Command code for {@link MediaController2#playFromMediaId(String, Bundle)}. - */ - public static final int COMMAND_CODE_SESSION_PLAY_FROM_MEDIA_ID = 22; - - /** - * Command code for {@link MediaController2#playFromUri(Uri, Bundle)}. - */ - public static final int COMMAND_CODE_SESSION_PLAY_FROM_URI = 23; - - /** - * Command code for {@link MediaController2#playFromSearch(String, Bundle)}. - */ - public static final int COMMAND_CODE_SESSION_PLAY_FROM_SEARCH = 24; - - /** - * Command code for {@link MediaController2#prepareFromMediaId(String, Bundle)}. - */ - public static final int COMMAND_CODE_SESSION_PREPARE_FROM_MEDIA_ID = 25; - - /** - * Command code for {@link MediaController2#prepareFromUri(Uri, Bundle)}. - */ - public static final int COMMAND_CODE_SESSION_PREPARE_FROM_URI = 26; - - /** - * Command code for {@link MediaController2#prepareFromSearch(String, Bundle)}. - */ - public static final int COMMAND_CODE_SESSION_PREPARE_FROM_SEARCH = 27; - - /** - * Command code for {@link MediaController2#setRating(String, Rating2)}. - */ - public static final int COMMAND_CODE_SESSION_SET_RATING = 28; - - // TODO(jaewan): Add javadoc - public static final int COMMAND_CODE_LIBRARY_GET_CHILDREN = 29; - public static final int COMMAND_CODE_LIBRARY_GET_ITEM = 30; - public static final int COMMAND_CODE_LIBRARY_GET_LIBRARY_ROOT = 31; - public static final int COMMAND_CODE_LIBRARY_GET_SEARCH_RESULT = 32; - public static final int COMMAND_CODE_LIBRARY_SEARCH = 33; - public static final int COMMAND_CODE_LIBRARY_SUBSCRIBE = 34; - public static final int COMMAND_CODE_LIBRARY_UNSUBSCRIBE = 35; - - // TODO(jaewan): Rename and move provider - private final MediaSession2Provider.CommandProvider mProvider; - - public SessionCommand2(int commandCode) { - mProvider = ApiLoader.getProvider().createMediaSession2Command( - this, commandCode, null, null); - } - - public SessionCommand2(@NonNull String action, @Nullable Bundle extras) { - if (action == null) { - throw new IllegalArgumentException("action shouldn't be null"); - } - mProvider = ApiLoader.getProvider().createMediaSession2Command( - this, COMMAND_CODE_CUSTOM, action, extras); - } - - /** - * @hide - */ - public MediaSession2Provider.CommandProvider getProvider() { - return mProvider; - } - - public int getCommandCode() { - return mProvider.getCommandCode_impl(); - } - - public @Nullable String getCustomCommand() { - return mProvider.getCustomCommand_impl(); - } - - public @Nullable Bundle getExtras() { - return mProvider.getExtras_impl(); - } - - /** - * @return a new Bundle instance from the Command - * @hide - */ - public Bundle toBundle() { - return mProvider.toBundle_impl(); - } - - @Override - public boolean equals(Object obj) { - if (!(obj instanceof SessionCommand2)) { - return false; - } - return mProvider.equals_impl(((SessionCommand2) obj).mProvider); - } - - @Override - public int hashCode() { - return mProvider.hashCode_impl(); - } - - /** - * @return a new Command instance from the Bundle - * @hide - */ - public static SessionCommand2 fromBundle(@NonNull Bundle command) { - return ApiLoader.getProvider().fromBundle_MediaSession2Command(command); - } -} diff --git a/media/java/android/media/SessionCommandGroup2.java b/media/java/android/media/SessionCommandGroup2.java deleted file mode 100644 index 399765e68b34..000000000000 --- a/media/java/android/media/SessionCommandGroup2.java +++ /dev/null @@ -1,106 +0,0 @@ -/* - * 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 android.media; - -import android.annotation.NonNull; -import android.annotation.Nullable; -import android.content.Context; -import android.media.update.ApiLoader; -import android.media.update.MediaSession2Provider; -import android.os.Bundle; - -import java.util.Set; - -/** - * @hide - * Represent set of {@link SessionCommand2}. - */ -public final class SessionCommandGroup2 { - // TODO(jaewan): Rename and move provider - private final MediaSession2Provider.CommandGroupProvider mProvider; - - public SessionCommandGroup2() { - mProvider = ApiLoader.getProvider().createMediaSession2CommandGroup(this, null); - } - - public SessionCommandGroup2(@Nullable SessionCommandGroup2 others) { - mProvider = ApiLoader.getProvider().createMediaSession2CommandGroup(this, others); - } - - /** - * @hide - */ - public SessionCommandGroup2(@NonNull MediaSession2Provider.CommandGroupProvider provider) { - mProvider = provider; - } - - public void addCommand(@NonNull SessionCommand2 command) { - mProvider.addCommand_impl(command); - } - - public void addCommand(int commandCode) { - // TODO(jaewna): Implement - } - - public void addAllPredefinedCommands() { - mProvider.addAllPredefinedCommands_impl(); - } - - public void removeCommand(@NonNull SessionCommand2 command) { - mProvider.removeCommand_impl(command); - } - - public void removeCommand(int commandCode) { - // TODO(jaewan): Implement. - } - - public boolean hasCommand(@NonNull SessionCommand2 command) { - return mProvider.hasCommand_impl(command); - } - - public boolean hasCommand(int code) { - return mProvider.hasCommand_impl(code); - } - - public @NonNull - Set<SessionCommand2> getCommands() { - return mProvider.getCommands_impl(); - } - - /** - * @hide - */ - public @NonNull MediaSession2Provider.CommandGroupProvider getProvider() { - return mProvider; - } - - /** - * @return new bundle from the CommandGroup - * @hide - */ - public @NonNull Bundle toBundle() { - return mProvider.toBundle_impl(); - } - - /** - * @return new instance of CommandGroup from the bundle - * @hide - */ - public static @Nullable SessionCommandGroup2 fromBundle(Bundle commands) { - return ApiLoader.getProvider().fromBundle_MediaSession2CommandGroup(commands); - } -} diff --git a/media/java/android/media/SessionToken2.java b/media/java/android/media/SessionToken2.java deleted file mode 100644 index f7d54f294619..000000000000 --- a/media/java/android/media/SessionToken2.java +++ /dev/null @@ -1,164 +0,0 @@ -/* - * 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 android.media; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.content.Context; -import android.media.session.MediaSessionManager; -import android.media.update.ApiLoader; -import android.media.update.SessionToken2Provider; -import android.os.Bundle; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @hide - * Represents an ongoing {@link MediaSession2}. - * If it's representing a session service, it may not be ongoing. - * <p> - * This may be passed to apps by the session owner to allow them to create a - * {@link MediaController2} to communicate with the session. - * <p> - * It can be also obtained by {@link MediaSessionManager}. - */ -// New version of MediaSession.Token for following reasons -// - Stop implementing Parcelable for updatable support -// - Represent session and library service (formerly browser service) in one class. -// Previously MediaSession.Token was for session and ComponentName was for service. -public final class SessionToken2 { - @Retention(RetentionPolicy.SOURCE) - @IntDef(value = {TYPE_SESSION, TYPE_SESSION_SERVICE, TYPE_LIBRARY_SERVICE}) - public @interface TokenType { - } - - public static final int TYPE_SESSION = 0; - public static final int TYPE_SESSION_SERVICE = 1; - public static final int TYPE_LIBRARY_SERVICE = 2; - - private final SessionToken2Provider mProvider; - - // From the return value of android.os.Process.getUidForName(String) when error - private static final int UID_UNKNOWN = -1; - - /** - * Constructor for the token. You can only create token for session service or library service - * to use by {@link MediaController2} or {@link MediaBrowser2}. - * - * @param context context - * @param packageName package name - * @param serviceName name of service. Can be {@code null} if it's not an service. - */ - public SessionToken2(@NonNull Context context, @NonNull String packageName, - @NonNull String serviceName) { - this(context, packageName, serviceName, UID_UNKNOWN); - } - - /** - * Constructor for the token. You can only create token for session service or library service - * to use by {@link MediaController2} or {@link MediaBrowser2}. - * - * @param context context - * @param packageName package name - * @param serviceName name of service. Can be {@code null} if it's not an service. - * @param uid uid of the app. - * @hide - */ - public SessionToken2(@NonNull Context context, @NonNull String packageName, - @NonNull String serviceName, int uid) { - mProvider = ApiLoader.getProvider().createSessionToken2( - context, this, packageName, serviceName, uid); - } - - /** - * Constructor for the token. - * @hide - */ - public SessionToken2(@NonNull SessionToken2Provider provider) { - mProvider = provider; - } - - @Override - public int hashCode() { - return mProvider.hashCode_impl(); - } - - @Override - public boolean equals(Object obj) { - return mProvider.equals_impl(obj); - } - - @Override - public String toString() { - return mProvider.toString_impl(); - } - - /** - * @hide - */ - public SessionToken2Provider getProvider() { - return mProvider; - } - - /** - * @return uid of the session - */ - public int getUid() { - return mProvider.getUid_impl(); - } - - /** - * @return package name - */ - public String getPackageName() { - return mProvider.getPackageName_impl(); - } - - /** - * @return id - */ - public String getId() { - return mProvider.getId_imp(); - } - - /** - * @return type of the token - * @see #TYPE_SESSION - * @see #TYPE_SESSION_SERVICE - */ - public @TokenType int getType() { - return mProvider.getType_impl(); - } - - /** - * Create a token from the bundle, exported by {@link #toBundle()}. - * @param bundle - * @return - */ - public static SessionToken2 fromBundle(@NonNull Bundle bundle) { - return ApiLoader.getProvider().fromBundle_SessionToken2(bundle); - } - - /** - * Create a {@link Bundle} from this token to share it across processes. - * @return Bundle - */ - public Bundle toBundle() { - return mProvider.toBundle_impl(); - } -} diff --git a/media/java/android/media/VolumeProvider2.java b/media/java/android/media/VolumeProvider2.java deleted file mode 100644 index 1a4608f707b6..000000000000 --- a/media/java/android/media/VolumeProvider2.java +++ /dev/null @@ -1,147 +0,0 @@ -/* - * 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 android.media; - -import android.annotation.IntDef; -import android.annotation.NonNull; -import android.media.update.ApiLoader; -import android.media.update.VolumeProvider2Provider; - -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; - -/** - * @hide - * Handles requests to adjust or set the volume on a session. This is also used - * to push volume updates back to the session. The provider must call - * {@link #setCurrentVolume(int)} each time the volume being provided changes. - * <p> - * You can set a volume provider on a session by calling - * {@link MediaSession2#updatePlayer}. - */ -// New version of VolumeProvider with following changes -// - Don't implement Parcelable for updatable support. -public abstract class VolumeProvider2 { - /** - * @hide - */ - @IntDef({VOLUME_CONTROL_FIXED, VOLUME_CONTROL_RELATIVE, VOLUME_CONTROL_ABSOLUTE}) - @Retention(RetentionPolicy.SOURCE) - public @interface ControlType {} - - /** - * The volume is fixed and can not be modified. Requests to change volume - * should be ignored. - */ - public static final int VOLUME_CONTROL_FIXED = 0; - - /** - * The volume control uses relative adjustment via - * {@link #onAdjustVolume(int)}. Attempts to set the volume to a specific - * value should be ignored. - */ - public static final int VOLUME_CONTROL_RELATIVE = 1; - - /** - * The volume control uses an absolute value. It may be adjusted using - * {@link #onAdjustVolume(int)} or set directly using - * {@link #onSetVolumeTo(int)}. - */ - public static final int VOLUME_CONTROL_ABSOLUTE = 2; - - private final VolumeProvider2Provider mProvider; - - /** - * Create a new volume provider for handling volume events. You must specify - * the type of volume control, the maximum volume that can be used, and the - * current volume on the output. - * - * @param controlType The method for controlling volume that is used by this provider. - * @param maxVolume The maximum allowed volume. - * @param currentVolume The current volume on the output. - */ - public VolumeProvider2(@ControlType int controlType, int maxVolume, int currentVolume) { - mProvider = ApiLoader.getProvider().createVolumeProvider2( - this, controlType, maxVolume, currentVolume); - } - - /** - * @hide - */ - public VolumeProvider2Provider getProvider() { - return mProvider; - } - - /** - * Get the volume control type that this volume provider uses. - * - * @return The volume control type for this volume provider - */ - @ControlType - public final int getControlType() { - return mProvider.getControlType_impl(); - } - - /** - * Get the maximum volume this provider allows. - * - * @return The max allowed volume. - */ - public final int getMaxVolume() { - return mProvider.getMaxVolume_impl(); - } - - /** - * Gets the current volume. This will be the last value set by - * {@link #setCurrentVolume(int)}. - * - * @return The current volume. - */ - public final int getCurrentVolume() { - return mProvider.getCurrentVolume_impl(); - } - - /** - * Notify the system that the current volume has been changed. This must be - * called every time the volume changes to ensure it is displayed properly. - * - * @param currentVolume The current volume on the output. - */ - public final void setCurrentVolume(int currentVolume) { - mProvider.setCurrentVolume_impl(currentVolume); - } - - /** - * Override to handle requests to set the volume of the current output. - * After the volume has been modified {@link #setCurrentVolume} must be - * called to notify the system. - * - * @param volume The volume to set the output to. - */ - public void onSetVolumeTo(int volume) { } - - /** - * Override to handle requests to adjust the volume of the current output. - * Direction will be one of {@link AudioManager#ADJUST_LOWER}, - * {@link AudioManager#ADJUST_RAISE}, {@link AudioManager#ADJUST_SAME}. - * After the volume has been modified {@link #setCurrentVolume} must be - * called to notify the system. - * - * @param direction The direction to change the volume in. - */ - public void onAdjustVolume(int direction) { } -} diff --git a/media/java/android/media/session/ISessionManager.aidl b/media/java/android/media/session/ISessionManager.aidl index 3578c160363e..4ced7bee2cbd 100644 --- a/media/java/android/media/session/ISessionManager.aidl +++ b/media/java/android/media/session/ISessionManager.aidl @@ -17,7 +17,6 @@ package android.media.session; import android.content.ComponentName; import android.media.IRemoteVolumeController; -import android.media.ISessionTokensListener; import android.media.session.IActiveSessionsListener; import android.media.session.ICallback; import android.media.session.IOnMediaKeyListener; @@ -55,12 +54,4 @@ interface ISessionManager { // MediaSession2 boolean isTrusted(String controllerPackageName, int controllerPid, int controllerUid); - boolean createSession2(in Bundle sessionToken); - void destroySession2(in Bundle sessionToken); - List<Bundle> getSessionTokens(boolean activeSessionOnly, boolean sessionServiceOnly, - String packageName); - - void addSessionTokensListener(in ISessionTokensListener listener, int userId, - String packageName); - void removeSessionTokensListener(in ISessionTokensListener listener, String packageName); } diff --git a/media/java/android/media/session/MediaSessionManager.java b/media/java/android/media/session/MediaSessionManager.java index 98f3fb27ef8a..8215779d2b13 100644 --- a/media/java/android/media/session/MediaSessionManager.java +++ b/media/java/android/media/session/MediaSessionManager.java @@ -26,11 +26,7 @@ import android.content.ComponentName; import android.content.Context; import android.media.AudioManager; import android.media.IRemoteVolumeController; -import android.media.ISessionTokensListener; -import android.media.MediaSession2; -import android.media.SessionToken2; import android.media.browse.MediaBrowser; -import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; @@ -44,10 +40,8 @@ import android.util.Log; import android.view.KeyEvent; import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.concurrent.Executor; /** * Provides support for interacting with {@link MediaSession media sessions} @@ -75,8 +69,6 @@ public final class MediaSessionManager { private final ArrayMap<OnActiveSessionsChangedListener, SessionsChangedWrapper> mListeners = new ArrayMap<OnActiveSessionsChangedListener, SessionsChangedWrapper>(); - private final ArrayMap<OnSessionTokensChangedListener, SessionTokensChangedWrapper> - mSessionTokensListener = new ArrayMap<>(); private final Object mLock = new Object(); private final ISessionManager mService; @@ -413,73 +405,6 @@ public final class MediaSessionManager { } /** - * Called when a {@link MediaSession2} is created. - * @hide - */ - public boolean createSession2(@NonNull SessionToken2 token) { - if (token == null) { - return false; - } - try { - return mService.createSession2(token.toBundle()); - } catch (RemoteException e) { - Log.wtf(TAG, "Cannot communicate with the service.", e); - } - return false; - } - - /** - * Called when a {@link MediaSession2} is destroyed. - * @hide - */ - public void destroySession2(@NonNull SessionToken2 token) { - if (token == null) { - return; - } - try { - mService.destroySession2(token.toBundle()); - } catch (RemoteException e) { - Log.wtf(TAG, "Cannot communicate with the service.", e); - } - } - - /** - * @hide - * Get {@link List} of {@link SessionToken2} whose sessions are active now. This list represents - * active sessions regardless of whether they're {@link MediaSession2}. - * <p> - * This requires the android.Manifest.permission.MEDIA_CONTENT_CONTROL permission be held by the - * calling app. You may also retrieve this list if your app is an enabled notification listener - * using the {@link NotificationListenerService} APIs. - * - * @return list of tokens - */ - public List<SessionToken2> getActiveSessionTokens() { - try { - List<Bundle> bundles = mService.getSessionTokens( - /* activeSessionOnly */ true, /* sessionServiceOnly */ false, - mContext.getOpPackageName()); - return toTokenList(bundles); - } catch (RemoteException e) { - Log.wtf(TAG, "Cannot communicate with the service.", e); - return Collections.emptyList(); - } - } - - private static List<SessionToken2> toTokenList(List<Bundle> bundles) { - List<SessionToken2> tokens = new ArrayList<>(); - if (bundles != null) { - for (int i = 0; i < bundles.size(); i++) { - SessionToken2 token = SessionToken2.fromBundle(bundles.get(i)); - if (token != null) { - tokens.add(token); - } - } - } - return tokens; - } - - /** * Check if the global priority session is currently active. This can be * used to decide if media keys should be sent to the session or to the app. * @@ -601,15 +526,6 @@ public final class MediaSessionManager { } /** - * @hide - * Listens for changes to the {@link #getAllSessionTokens()}. This can be added - * using {@link #addOnActiveSessionsChangedListener}. - */ - public interface OnSessionTokensChangedListener { - void onSessionTokensChanged(@NonNull List<SessionToken2> tokens); - } - - /** * Listens the volume key long-presses. * @hide */ @@ -815,41 +731,6 @@ public final class MediaSessionManager { } } - private static final class SessionTokensChangedWrapper { - private Context mContext; - private Executor mExecutor; - private OnSessionTokensChangedListener mListener; - - public SessionTokensChangedWrapper(Context context, Executor executor, - OnSessionTokensChangedListener listener) { - mContext = context; - mExecutor = executor; - mListener = listener; - } - - private final ISessionTokensListener.Stub mStub = new ISessionTokensListener.Stub() { - @Override - public void onSessionTokensChanged(final List<Bundle> bundles) { - final Executor executor = mExecutor; - if (executor != null) { - executor.execute(() -> { - final Context context = mContext; - final OnSessionTokensChangedListener listener = mListener; - if (context != null && listener != null) { - listener.onSessionTokensChanged(toTokenList(bundles)); - } - }); - } - } - }; - - private void release() { - mListener = null; - mContext = null; - mExecutor = null; - } - } - private static final class OnVolumeKeyLongPressListenerImpl extends IOnVolumeKeyLongPressListener.Stub { private OnVolumeKeyLongPressListener mListener; diff --git a/media/java/android/media/update/ApiLoader.java b/media/java/android/media/update/ApiLoader.java deleted file mode 100644 index 0c1d1a2fc8d2..000000000000 --- a/media/java/android/media/update/ApiLoader.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2017 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 android.media.update; - -import android.app.ActivityManager; -import android.app.AppGlobals; -import android.content.pm.ApplicationInfo; -import android.content.pm.PackageManager; -import android.content.pm.PackageManager.NameNotFoundException; -import android.os.Build; -import android.os.RemoteException; -import android.os.UserHandle; - -import com.android.internal.annotations.GuardedBy; - -import dalvik.system.PathClassLoader; - -import java.io.File; - -/** - * @hide - */ -public final class ApiLoader { - @GuardedBy("this") - private static StaticProvider sMediaUpdatable; - - private static final String UPDATE_PACKAGE = "com.android.media.update"; - private static final String UPDATE_CLASS = "com.android.media.update.ApiFactory"; - private static final String UPDATE_METHOD = "initialize"; - private static final boolean REGISTER_UPDATE_DEPENDENCY = true; - - private ApiLoader() { } - - public static StaticProvider getProvider() { - try { - return getMediaUpdatable(); - } catch (RemoteException e) { - throw e.rethrowFromSystemServer(); - } catch (NameNotFoundException | ReflectiveOperationException e) { - throw new RuntimeException(e); - } - } - - // TODO This method may do I/O; Ensure it does not violate (emit warnings in) strict mode. - private static synchronized StaticProvider getMediaUpdatable() - throws NameNotFoundException, ReflectiveOperationException, RemoteException { - if (sMediaUpdatable != null) return sMediaUpdatable; - - // TODO Figure out when to use which package (query media update service) - int flags = Build.IS_DEBUGGABLE ? 0 : PackageManager.MATCH_SYSTEM_ONLY; - ApplicationInfo ai = AppGlobals.getPackageManager().getApplicationInfo( - UPDATE_PACKAGE, flags, UserHandle.myUserId()); - - if (REGISTER_UPDATE_DEPENDENCY) { - // Register a dependency to the updatable in order to be killed during updates - ActivityManager.getService().addPackageDependency(ai.packageName); - } - - ClassLoader classLoader = new PathClassLoader(ai.sourceDir, - ai.nativeLibraryDir + File.pathSeparator + System.getProperty("java.library.path"), - ClassLoader.getSystemClassLoader().getParent()); - return sMediaUpdatable = (StaticProvider) classLoader.loadClass(UPDATE_CLASS) - .getMethod(UPDATE_METHOD, ApplicationInfo.class).invoke(null, ai); - } -} diff --git a/media/java/android/media/update/MediaController2Provider.java b/media/java/android/media/update/MediaController2Provider.java deleted file mode 100644 index 7234f7b61656..000000000000 --- a/media/java/android/media/update/MediaController2Provider.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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 android.media.update; - -import android.app.PendingIntent; -import android.media.AudioAttributes; -import android.media.MediaController2.PlaybackInfo; -import android.media.MediaItem2; -import android.media.MediaMetadata2; -import android.media.SessionCommand2; -import android.media.Rating2; -import android.media.SessionToken2; -import android.net.Uri; -import android.os.Bundle; -import android.os.ResultReceiver; - -import java.util.List; - -/** - * @hide - */ -public interface MediaController2Provider extends TransportControlProvider { - void initialize(); - - void close_impl(); - SessionToken2 getSessionToken_impl(); - boolean isConnected_impl(); - - PendingIntent getSessionActivity_impl(); - - void setVolumeTo_impl(int value, int flags); - void adjustVolume_impl(int direction, int flags); - PlaybackInfo getPlaybackInfo_impl(); - - void prepareFromUri_impl(Uri uri, Bundle extras); - void prepareFromSearch_impl(String query, Bundle extras); - void prepareFromMediaId_impl(String mediaId, Bundle extras); - void playFromSearch_impl(String query, Bundle extras); - void playFromUri_impl(Uri uri, Bundle extras); - void playFromMediaId_impl(String mediaId, Bundle extras); - void fastForward_impl(); - void rewind_impl(); - - void setRating_impl(String mediaId, Rating2 rating); - void sendCustomCommand_impl(SessionCommand2 command, Bundle args, ResultReceiver cb); - List<MediaItem2> getPlaylist_impl(); - void setPlaylist_impl(List<MediaItem2> list, MediaMetadata2 metadata); - MediaMetadata2 getPlaylistMetadata_impl(); - void updatePlaylistMetadata_impl(MediaMetadata2 metadata); - - void addPlaylistItem_impl(int index, MediaItem2 item); - void replacePlaylistItem_impl(int index, MediaItem2 item); - void removePlaylistItem_impl(MediaItem2 item); - - int getPlayerState_impl(); - long getCurrentPosition_impl(); - float getPlaybackSpeed_impl(); - long getBufferedPosition_impl(); - MediaItem2 getCurrentMediaItem_impl(); - - interface PlaybackInfoProvider { - int getPlaybackType_impl(); - AudioAttributes getAudioAttributes_impl(); - int getControlType_impl(); - int getMaxVolume_impl(); - int getCurrentVolume_impl(); - } -} diff --git a/media/java/android/media/update/MediaItem2Provider.java b/media/java/android/media/update/MediaItem2Provider.java deleted file mode 100644 index 47db22f22d98..000000000000 --- a/media/java/android/media/update/MediaItem2Provider.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * 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 android.media.update; - -import android.media.DataSourceDesc; -import android.media.MediaItem2; -import android.media.MediaItem2.Builder; -import android.media.MediaMetadata2; -import android.os.Bundle; - -/** - * @hide - */ -public interface MediaItem2Provider { - Bundle toBundle_impl(); - String toString_impl(); - int getFlags_impl(); - boolean isBrowsable_impl(); - boolean isPlayable_impl(); - void setMetadata_impl(MediaMetadata2 metadata); - MediaMetadata2 getMetadata_impl(); - String getMediaId_impl(); - DataSourceDesc getDataSourceDesc_impl(); - boolean equals_impl(Object obj); - - interface BuilderProvider { - Builder setMediaId_impl(String mediaId); - Builder setMetadata_impl(MediaMetadata2 metadata); - Builder setDataSourceDesc_impl(DataSourceDesc dataSourceDesc); - MediaItem2 build_impl(); - } -} diff --git a/media/java/android/media/update/MediaMetadata2Provider.java b/media/java/android/media/update/MediaMetadata2Provider.java deleted file mode 100644 index 22463e924075..000000000000 --- a/media/java/android/media/update/MediaMetadata2Provider.java +++ /dev/null @@ -1,38 +0,0 @@ -package android.media.update; - -import android.graphics.Bitmap; -import android.media.MediaMetadata2; -import android.media.MediaMetadata2.Builder; -import android.media.Rating2; -import android.os.Bundle; - -import java.util.Set; - -/** - * @hide - */ -public interface MediaMetadata2Provider { - boolean containsKey_impl(String key); - CharSequence getText_impl(String key); - String getMediaId_impl(); - String getString_impl(String key); - long getLong_impl(String key); - Rating2 getRating_impl(String key); - Bundle toBundle_impl(); - Set<String> keySet_impl(); - int size_impl(); - Bitmap getBitmap_impl(String key); - float getFloat_impl(String key); - Bundle getExtras_impl(); - - interface BuilderProvider { - Builder putText_impl(String key, CharSequence value); - Builder putString_impl(String key, String value); - Builder putLong_impl(String key, long value); - Builder putRating_impl(String key, Rating2 value); - Builder putBitmap_impl(String key, Bitmap value); - Builder putFloat_impl(String key, float value); - Builder setExtras_impl(Bundle bundle); - MediaMetadata2 build_impl(); - } -} diff --git a/media/java/android/media/update/MediaPlaylistAgentProvider.java b/media/java/android/media/update/MediaPlaylistAgentProvider.java deleted file mode 100644 index e1522cf5b619..000000000000 --- a/media/java/android/media/update/MediaPlaylistAgentProvider.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * 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 android.media.update; - -import android.media.DataSourceDesc; -import android.media.MediaItem2; -import android.media.MediaMetadata2; -import android.media.MediaPlaylistAgent.PlaylistEventCallback; - -import java.util.List; -import java.util.concurrent.Executor; - -/** - * @hide - */ -public interface MediaPlaylistAgentProvider { - // final methods of MediaPlaylistAgent - void registerPlaylistEventCallback_impl(Executor executor, PlaylistEventCallback callback); - void unregisterPlaylistEventCallback_impl(PlaylistEventCallback callback); - void notifyPlaylistChanged_impl(); - void notifyPlaylistMetadataChanged_impl(); - void notifyShuffleModeChanged_impl(); - void notifyRepeatModeChanged_impl(); - - // public methods of MediaPlaylistAgent - List<MediaItem2> getPlaylist_impl(); - void setPlaylist_impl(List<MediaItem2> list, MediaMetadata2 metadata); - MediaMetadata2 getPlaylistMetadata_impl(); - void updatePlaylistMetadata_impl(MediaMetadata2 metadata); - void addPlaylistItem_impl(int index, MediaItem2 item); - void removePlaylistItem_impl(MediaItem2 item); - void replacePlaylistItem_impl(int index, MediaItem2 item); - void skipToPlaylistItem_impl(MediaItem2 item); - void skipToPreviousItem_impl(); - void skipToNextItem_impl(); - int getRepeatMode_impl(); - void setRepeatMode_impl(int repeatMode); - int getShuffleMode_impl(); - void setShuffleMode_impl(int shuffleMode); - MediaItem2 getMediaItem_impl(DataSourceDesc dsd); -} diff --git a/media/java/android/media/update/MediaSession2Provider.java b/media/java/android/media/update/MediaSession2Provider.java deleted file mode 100644 index 475134861105..000000000000 --- a/media/java/android/media/update/MediaSession2Provider.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * 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 android.media.update; - -import android.app.PendingIntent; -import android.media.AudioFocusRequest; -import android.media.MediaItem2; -import android.media.MediaMetadata2; -import android.media.MediaPlayerBase; -import android.media.MediaPlaylistAgent; -import android.media.MediaSession2; -import android.media.SessionCommand2; -import android.media.MediaSession2.CommandButton; -import android.media.MediaSession2.CommandButton.Builder; -import android.media.SessionCommandGroup2; -import android.media.MediaSession2.ControllerInfo; -import android.media.MediaSession2.OnDataSourceMissingHelper; -import android.media.MediaSession2.SessionCallback; -import android.media.SessionToken2; -import android.media.VolumeProvider2; -import android.os.Bundle; -import android.os.ResultReceiver; - -import java.util.List; -import java.util.Set; -import java.util.concurrent.Executor; - -/** - * @hide - */ -public interface MediaSession2Provider extends TransportControlProvider { - void close_impl(); - void updatePlayer_impl(MediaPlayerBase player, MediaPlaylistAgent playlistAgent, - VolumeProvider2 volumeProvider); - MediaPlayerBase getPlayer_impl(); - MediaMetadata2 getPlaylistMetadata_impl(); - void updatePlaylistMetadata_impl(MediaMetadata2 metadata); - MediaPlaylistAgent getPlaylistAgent_impl(); - VolumeProvider2 getVolumeProvider_impl(); - SessionToken2 getToken_impl(); - List<ControllerInfo> getConnectedControllers_impl(); - void setCustomLayout_impl(ControllerInfo controller, List<CommandButton> layout); - void setAudioFocusRequest_impl(AudioFocusRequest afr); - void setAllowedCommands_impl(ControllerInfo controller, SessionCommandGroup2 commands); - void sendCustomCommand_impl(ControllerInfo controller, SessionCommand2 command, Bundle args, - ResultReceiver receiver); - void sendCustomCommand_impl(SessionCommand2 command, Bundle args); - void addPlaylistItem_impl(int index, MediaItem2 item); - void removePlaylistItem_impl(MediaItem2 item); - void replacePlaylistItem_impl(int index, MediaItem2 item); - List<MediaItem2> getPlaylist_impl(); - void setPlaylist_impl(List<MediaItem2> list, MediaMetadata2 metadata); - MediaItem2 getCurrentPlaylistItem_impl(); - void notifyError_impl(int errorCode, Bundle extras); - int getPlayerState_impl(); - long getCurrentPosition_impl(); - long getBufferedPosition_impl(); - void setOnDataSourceMissingHelper_impl(OnDataSourceMissingHelper helper); - void clearOnDataSourceMissingHelper_impl(); - - // TODO(jaewan): Rename and move provider - interface CommandProvider { - int getCommandCode_impl(); - String getCustomCommand_impl(); - Bundle getExtras_impl(); - Bundle toBundle_impl(); - - boolean equals_impl(Object ob); - int hashCode_impl(); - } - - // TODO(jaewan): Rename and move provider - interface CommandGroupProvider { - void addCommand_impl(SessionCommand2 command); - void addAllPredefinedCommands_impl(); - void removeCommand_impl(SessionCommand2 command); - boolean hasCommand_impl(SessionCommand2 command); - boolean hasCommand_impl(int code); - Set<SessionCommand2> getCommands_impl(); - Bundle toBundle_impl(); - } - - interface CommandButtonProvider { - SessionCommand2 getCommand_impl(); - int getIconResId_impl(); - String getDisplayName_impl(); - Bundle getExtras_impl(); - boolean isEnabled_impl(); - - interface BuilderProvider { - Builder setCommand_impl(SessionCommand2 command); - Builder setIconResId_impl(int resId); - Builder setDisplayName_impl(String displayName); - Builder setEnabled_impl(boolean enabled); - Builder setExtras_impl(Bundle extras); - CommandButton build_impl(); - } - } - - interface ControllerInfoProvider { - String getPackageName_impl(); - int getUid_impl(); - boolean isTrusted_impl(); - int hashCode_impl(); - boolean equals_impl(Object obj); - String toString_impl(); - } - - interface BuilderBaseProvider<T extends MediaSession2, C extends SessionCallback> { - void setPlayer_impl(MediaPlayerBase player); - void setPlaylistAgent_impl(MediaPlaylistAgent playlistAgent); - void setVolumeProvider_impl(VolumeProvider2 volumeProvider); - void setSessionActivity_impl(PendingIntent pi); - void setId_impl(String id); - void setSessionCallback_impl(Executor executor, C callback); - T build_impl(); - } -} diff --git a/media/java/android/media/update/ProviderCreator.java b/media/java/android/media/update/ProviderCreator.java deleted file mode 100644 index f5f3e470812f..000000000000 --- a/media/java/android/media/update/ProviderCreator.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * 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 android.media.update; - -/** @hide */ -@FunctionalInterface -public interface ProviderCreator<T, U> { - U createProvider(T instance); -} diff --git a/media/java/android/media/update/Rating2Provider.java b/media/java/android/media/update/Rating2Provider.java deleted file mode 100644 index 28ad2735d63c..000000000000 --- a/media/java/android/media/update/Rating2Provider.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * 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 android.media.update; - -import android.annotation.SystemApi; -import android.os.Bundle; - -/** - * @hide - */ -public interface Rating2Provider { - String toString_impl(); - boolean equals_impl(Object obj); - int hashCode_impl(); - Bundle toBundle_impl(); - boolean isRated_impl(); - int getRatingStyle_impl(); - boolean hasHeart_impl(); - boolean isThumbUp_impl(); - float getStarRating_impl(); - float getPercentRating_impl(); -} diff --git a/media/java/android/media/update/StaticProvider.java b/media/java/android/media/update/StaticProvider.java deleted file mode 100644 index ccb8c0263611..000000000000 --- a/media/java/android/media/update/StaticProvider.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2017 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 android.media.update; - -import android.content.Context; -import android.media.MediaController2; -import android.media.MediaController2.ControllerCallback; -import android.media.MediaItem2; -import android.media.MediaMetadata2; -import android.media.MediaPlaylistAgent; -import android.media.MediaSession2; -import android.media.MediaSession2.SessionCallback; -import android.media.Rating2; -import android.media.SessionCommand2; -import android.media.SessionCommandGroup2; -import android.media.SessionToken2; -import android.media.VolumeProvider2; -import android.media.update.MediaSession2Provider.BuilderBaseProvider; -import android.media.update.MediaSession2Provider.CommandButtonProvider; -import android.media.update.MediaSession2Provider.CommandGroupProvider; -import android.media.update.MediaSession2Provider.CommandProvider; -import android.media.update.MediaSession2Provider.ControllerInfoProvider; -import android.os.Bundle; -import android.os.IInterface; - -import java.util.concurrent.Executor; - -/** - * Interface for connecting the public API to an updatable implementation. - * - * This interface provides access to constructors and static methods that are otherwise not directly - * accessible via an implementation object. - * @hide - */ -public interface StaticProvider { - CommandProvider createMediaSession2Command(SessionCommand2 instance, - int commandCode, String action, Bundle extra); - SessionCommand2 fromBundle_MediaSession2Command(Bundle bundle); - CommandGroupProvider createMediaSession2CommandGroup(SessionCommandGroup2 instance, - SessionCommandGroup2 others); - SessionCommandGroup2 fromBundle_MediaSession2CommandGroup(Bundle bundle); - ControllerInfoProvider createMediaSession2ControllerInfo(Context context, - MediaSession2.ControllerInfo instance, int uid, int pid, - String packageName, IInterface callback); - CommandButtonProvider.BuilderProvider createMediaSession2CommandButtonBuilder( - MediaSession2.CommandButton.Builder instance); - BuilderBaseProvider<MediaSession2, SessionCallback> createMediaSession2Builder( - Context context, MediaSession2.Builder instance); - - MediaController2Provider createMediaController2(Context context, MediaController2 instance, - SessionToken2 token, Executor executor, ControllerCallback callback); - - SessionToken2Provider createSessionToken2(Context context, SessionToken2 instance, - String packageName, String serviceName, int uid); - SessionToken2 fromBundle_SessionToken2(Bundle bundle); - - MediaItem2Provider.BuilderProvider createMediaItem2Builder(MediaItem2.Builder instance, - int flags); - MediaItem2 fromBundle_MediaItem2(Bundle bundle); - - VolumeProvider2Provider createVolumeProvider2(VolumeProvider2 instance, int controlType, - int maxVolume, int currentVolume); - - MediaMetadata2 fromBundle_MediaMetadata2(Bundle bundle); - MediaMetadata2Provider.BuilderProvider createMediaMetadata2Builder( - MediaMetadata2.Builder instance); - MediaMetadata2Provider.BuilderProvider createMediaMetadata2Builder( - MediaMetadata2.Builder instance, MediaMetadata2 source); - - Rating2 newUnratedRating_Rating2(int ratingStyle); - Rating2 fromBundle_Rating2(Bundle bundle); - Rating2 newHeartRating_Rating2(boolean hasHeart); - Rating2 newThumbRating_Rating2(boolean thumbIsUp); - Rating2 newStarRating_Rating2(int starRatingStyle, float starRating); - Rating2 newPercentageRating_Rating2(float percent); - - MediaPlaylistAgentProvider createMediaPlaylistAgent(MediaPlaylistAgent instance); -} diff --git a/media/java/android/media/update/TransportControlProvider.java b/media/java/android/media/update/TransportControlProvider.java deleted file mode 100644 index d89a88ab6970..000000000000 --- a/media/java/android/media/update/TransportControlProvider.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 android.media.update; - -import android.media.MediaItem2; - -/** - * @hide - */ -public interface TransportControlProvider { - void play_impl(); - void pause_impl(); - void stop_impl(); - void skipToPreviousItem_impl(); - void skipToNextItem_impl(); - - void prepare_impl(); - void seekTo_impl(long pos); - void skipToPlaylistItem_impl(MediaItem2 item); - - int getRepeatMode_impl(); - void setRepeatMode_impl(int repeatMode); - int getShuffleMode_impl(); - void setShuffleMode_impl(int shuffleMode); -} diff --git a/media/java/android/media/update/VolumeProvider2Provider.java b/media/java/android/media/update/VolumeProvider2Provider.java deleted file mode 100644 index 5b5cfd32b58d..000000000000 --- a/media/java/android/media/update/VolumeProvider2Provider.java +++ /dev/null @@ -1,26 +0,0 @@ -/* - * 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 android.media.update; - -/** - * @hide - */ -public interface VolumeProvider2Provider { - int getControlType_impl(); - int getMaxVolume_impl(); - int getCurrentVolume_impl(); - void setCurrentVolume_impl(int currentVolume); -} diff --git a/services/core/java/com/android/server/media/MediaSessionService.java b/services/core/java/com/android/server/media/MediaSessionService.java index 9d402b33546e..c18a79fc183c 100644 --- a/services/core/java/com/android/server/media/MediaSessionService.java +++ b/services/core/java/com/android/server/media/MediaSessionService.java @@ -16,10 +16,7 @@ package com.android.server.media; -import static android.media.SessionToken2.TYPE_SESSION; - import android.app.ActivityManager; -import android.app.AppGlobals; import android.app.INotificationManager; import android.app.KeyguardManager; import android.app.PendingIntent; @@ -30,7 +27,6 @@ import android.content.ComponentName; import android.content.ContentResolver; import android.content.Context; import android.content.Intent; -import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.PackageManager.NameNotFoundException; import android.content.pm.UserInfo; @@ -40,9 +36,6 @@ import android.media.AudioPlaybackConfiguration; import android.media.AudioSystem; import android.media.IAudioService; import android.media.IRemoteVolumeController; -import android.media.ISessionTokensListener; -import android.media.MediaController2; -import android.media.SessionToken2; import android.media.session.IActiveSessionsListener; import android.media.session.ICallback; import android.media.session.IOnMediaKeyListener; @@ -68,7 +61,6 @@ import android.os.UserManager; import android.provider.Settings; import android.speech.RecognizerIntent; import android.text.TextUtils; -import android.util.ArrayMap; import android.util.Log; import android.util.Slog; import android.util.SparseArray; @@ -85,15 +77,12 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; -import java.util.Map; -import java.util.NoSuchElementException; /** * System implementation of MediaSessionManager */ public class MediaSessionService extends SystemService implements Monitor { private static final String TAG = "MediaSessionService"; - static final boolean USE_MEDIA2_APIS = false; // TODO: Change this to true when we're ready. static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); // Leave log for key event always. private static final boolean DEBUG_KEY_EVENT = true; @@ -113,7 +102,6 @@ public class MediaSessionService extends SystemService implements Monitor { private final PowerManager.WakeLock mMediaEventWakeLock; private final int mLongPressTimeout; private final INotificationManager mNotificationManager; - private final IPackageManager mPackageManager; private KeyguardManager mKeyguardManager; private IAudioService mAudioService; @@ -131,13 +119,6 @@ public class MediaSessionService extends SystemService implements Monitor { // better way to handle this. private IRemoteVolumeController mRvc; - // MediaSession2 support - // TODO(jaewan): Support multi-user and managed profile. (b/73597722) - // TODO(jaewan): Make it priority list for handling volume/media key. (b/73760382) - private final Map<SessionToken2, MediaController2> mSessionRecords = new ArrayMap<>(); - - private final List<SessionTokensListenerRecord> mSessionTokensListeners = new ArrayList<>(); - public MediaSessionService(Context context) { super(context); mSessionManagerImpl = new SessionManagerImpl(); @@ -146,7 +127,6 @@ public class MediaSessionService extends SystemService implements Monitor { mLongPressTimeout = ViewConfiguration.getLongPressTimeout(); mNotificationManager = INotificationManager.Stub.asInterface( ServiceManager.getService(Context.NOTIFICATION_SERVICE)); - mPackageManager = AppGlobals.getPackageManager(); } @Override @@ -645,20 +625,6 @@ public class MediaSessionService extends SystemService implements Monitor { return mUserRecords.get(fullUserId); } - void destroySession2Internal(SessionToken2 token) { - synchronized (mLock) { - boolean notifySessionTokensUpdated = false; - if (token.getType() == SessionToken2.TYPE_SESSION) { - notifySessionTokensUpdated |= removeSessionRecordLocked(token); - } else { - notifySessionTokensUpdated |= addSessionRecordLocked(token); - } - if (notifySessionTokensUpdated) { - postSessionTokensUpdated(UserHandle.getUserId(token.getUid())); - } - } - } - /** * Information about a full user and its corresponding managed profiles. * @@ -1417,163 +1383,6 @@ public class MediaSessionService extends SystemService implements Monitor { } } - /** - * Called when a {@link android.media.MediaSession2} instance is created. - * <p> - * This does two things. - * 1. Keep the newly created session in the service - * 2. Do sanity check to ensure unique id per package, and return result - * - * @param sessionToken SessionToken2 object in bundled form - * @return {@code true} if the session's id isn't used by the package now. {@code false} - * otherwise. - */ - @Override - public boolean createSession2(Bundle sessionToken) { - if (!USE_MEDIA2_APIS) { - return false; - } - final int uid = Binder.getCallingUid(); - final SessionToken2 token = SessionToken2.fromBundle(sessionToken); - if (token == null || token.getUid() != uid) { - Log.w(TAG, "onSessionCreated failed, expected caller uid=" + token.getUid() - + " but from uid=" + uid); - } - if (DEBUG) { - Log.d(TAG, "createSession2: " + token); - } - synchronized (mLock) { - MediaController2 controller = mSessionRecords.get(token); - if (controller != null && controller.isConnected()) { - return false; - } - Context context = getContext(); - controller = new MediaController2(context, token, context.getMainExecutor(), - new ControllerCallback(token)); - if (addSessionRecordLocked(token, controller)) { - postSessionTokensUpdated(UserHandle.getUserId(token.getUid())); - } - return true; - } - } - - /** - * Called when a {@link android.media.MediaSession2} instance is closed. (i.e. destroyed) - * <p> - * Ideally service should know that a session is destroyed through the - * {@link android.media.MediaController2.ControllerCallback#onDisconnected()}, which is - * asynchronous call. However, we also need synchronous way together to address timing - * issue. If the package recreates the session almost immediately, which happens commonly - * for tests, service will reject the creation through {@link #onSessionCreated(Bundle)} - * if the service hasn't notified previous destroy yet. This synchronous API will address - * the issue. - * - * @param sessionToken SessionToken2 object in bundled form - */ - @Override - public void destroySession2(Bundle sessionToken) { - if (!USE_MEDIA2_APIS) { - return; - } - final int uid = Binder.getCallingUid(); - final SessionToken2 token = SessionToken2.fromBundle(sessionToken); - if (token == null || token.getUid() != uid) { - Log.w(TAG, "onSessionDestroyed failed, expected caller uid=" + token.getUid() - + " but from uid=" + uid); - } - if (DEBUG) { - Log.d(TAG, "destroySession2 " + token); - } - destroySession2Internal(token); - } - - // TODO(jaewan): Make this API take userId as an argument (b/73597722) - @Override - public List<Bundle> getSessionTokens(boolean activeSessionOnly, - boolean sessionServiceOnly, String packageName) throws RemoteException { - if (!USE_MEDIA2_APIS) { - return null; - } - final int pid = Binder.getCallingPid(); - final int uid = Binder.getCallingUid(); - final long token = Binder.clearCallingIdentity(); - - List<Bundle> tokens = new ArrayList<>(); - try { - verifySessionsRequest2(UserHandle.getUserId(uid), packageName, pid, uid); - synchronized (mLock) { - for (Map.Entry<SessionToken2, MediaController2> record - : mSessionRecords.entrySet()) { - boolean isSessionService = (record.getKey().getType() != TYPE_SESSION); - boolean isActive = record.getValue() != null; - if ((activeSessionOnly && !isActive) - || (sessionServiceOnly && !isSessionService)) { - continue; - } - tokens.add(record.getKey().toBundle()); - } - } - } finally { - Binder.restoreCallingIdentity(token); - } - return tokens; - } - - @Override - public void addSessionTokensListener(ISessionTokensListener listener, int userId, - String packageName) throws RemoteException { - if (!USE_MEDIA2_APIS) { - return; - } - final int pid = Binder.getCallingPid(); - final int uid = Binder.getCallingUid(); - final long token = Binder.clearCallingIdentity(); - try { - int resolvedUserId = verifySessionsRequest2(userId, packageName, pid, uid); - synchronized (mLock) { - final SessionTokensListenerRecord record = - new SessionTokensListenerRecord(listener, resolvedUserId); - try { - listener.asBinder().linkToDeath(record, 0); - } catch (RemoteException e) { - } - mSessionTokensListeners.add(record); - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - - // TODO(jaewan): Make this API take userId as an argument (b/73597722) - @Override - public void removeSessionTokensListener(ISessionTokensListener listener, - String packageName) throws RemoteException { - if (!USE_MEDIA2_APIS) { - return; - } - final int pid = Binder.getCallingPid(); - final int uid = Binder.getCallingUid(); - final long token = Binder.clearCallingIdentity(); - try { - verifySessionsRequest2(UserHandle.getUserId(uid), packageName, pid, uid); - synchronized (mLock) { - IBinder listenerBinder = listener.asBinder(); - for (SessionTokensListenerRecord record : mSessionTokensListeners) { - if (listenerBinder.equals(record.mListener.asBinder())) { - try { - listenerBinder.unlinkToDeath(record, 0); - } catch (NoSuchElementException e) { - } - mSessionTokensListeners.remove(record); - break; - } - } - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - // For MediaSession private int verifySessionsRequest(ComponentName componentName, int userId, final int pid, final int uid) { @@ -1594,23 +1403,6 @@ public class MediaSessionService extends SystemService implements Monitor { return resolvedUserId; } - // For MediaSession2 - private int verifySessionsRequest2(int targetUserId, String callerPackageName, - int callerPid, int callerUid) throws RemoteException { - // Check that they can make calls on behalf of the user and get the final user id. - int resolvedUserId = ActivityManager.handleIncomingUser(callerPid, callerUid, - targetUserId, true /* allowAll */, true /* requireFull */, "getSessionTokens", - callerPackageName); - // Check if they have the permissions or their component is - // enabled for the user they're calling from. - if (!hasMediaControlPermission( - resolvedUserId, callerPackageName, callerPid, callerUid)) { - throw new SecurityException("Missing permission to control media."); - } - return resolvedUserId; - } - - // For MediaSession2 private boolean hasMediaControlPermission(int resolvedUserId, String packageName, int pid, int uid) throws RemoteException { // Allow API calls from the System UI @@ -2014,7 +1806,6 @@ public class MediaSessionService extends SystemService implements Monitor { final class MessageHandler extends Handler { private static final int MSG_SESSIONS_CHANGED = 1; private static final int MSG_VOLUME_INITIAL_DOWN = 2; - private static final int MSG_SESSIONS_TOKENS_CHANGED = 3; private final SparseArray<Integer> mIntegerCache = new SparseArray<>(); @Override @@ -2033,9 +1824,6 @@ public class MediaSessionService extends SystemService implements Monitor { } } break; - case MSG_SESSIONS_TOKENS_CHANGED: - pushSessionTokensChanged((int) msg.obj); - break; } } @@ -2050,86 +1838,4 @@ public class MediaSessionService extends SystemService implements Monitor { obtainMessage(MSG_SESSIONS_CHANGED, userIdInteger).sendToTarget(); } } - - private class ControllerCallback extends MediaController2.ControllerCallback { - - private final SessionToken2 mToken; - - ControllerCallback(SessionToken2 token) { - mToken = token; - } - - @Override - public void onDisconnected(MediaController2 controller) { - destroySession2Internal(mToken); - } - }; - - private final class SessionTokensListenerRecord implements IBinder.DeathRecipient { - private final ISessionTokensListener mListener; - private final int mUserId; - - public SessionTokensListenerRecord(ISessionTokensListener listener, int userId) { - mListener = listener; - // TODO(jaewan): should userId be mapped through mFullUserIds? (b/73597722) - mUserId = userId; - } - - @Override - public void binderDied() { - synchronized (mLock) { - mSessionTokensListeners.remove(this); - } - } - } - - private void postSessionTokensUpdated(int userId) { - mHandler.obtainMessage(MessageHandler.MSG_SESSIONS_TOKENS_CHANGED, userId).sendToTarget(); - } - - private void pushSessionTokensChanged(int userId) { - synchronized (mLock) { - List<Bundle> tokens = new ArrayList<>(); - for (SessionToken2 token : mSessionRecords.keySet()) { - if (UserHandle.getUserId(token.getUid()) == userId) { - tokens.add(token.toBundle()); - } - } - - for (SessionTokensListenerRecord record : mSessionTokensListeners) { - // TODO(jaewan): Should userId be mapped through mFullUserIds? (b/73760382) - if (record.mUserId == userId || record.mUserId == UserHandle.USER_ALL) { - try { - record.mListener.onSessionTokensChanged(tokens); - } catch (RemoteException e) { - Log.w(TAG, "Failed to notify session tokens changed", e); - } - } - } - } - } - - private boolean addSessionRecordLocked(SessionToken2 token) { - return addSessionRecordLocked(token, null); - } - - private boolean addSessionRecordLocked(SessionToken2 token, MediaController2 controller) { - if (mSessionRecords.containsKey(token) && mSessionRecords.get(token) == controller) { - // The key/value pair already exists, no need to update. - return false; - } - - mSessionRecords.put(token, controller); - return true; - } - - private boolean removeSessionRecordLocked(SessionToken2 token) { - if (!mSessionRecords.containsKey(token)) { - // The key is already removed, no need to remove. - return false; - } - - mSessionRecords.remove(token); - return true; - } } |