Home | History | Annotate | Download | only in media
      1 /*
      2  * Copyright 2018 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package android.media;
     18 
     19 import android.annotation.CallbackExecutor;
     20 import android.annotation.IntDef;
     21 import android.annotation.NonNull;
     22 import android.annotation.Nullable;
     23 import android.media.update.ApiLoader;
     24 import android.media.update.MediaPlaylistAgentProvider;
     25 
     26 import java.lang.annotation.Retention;
     27 import java.lang.annotation.RetentionPolicy;
     28 import java.util.List;
     29 import java.util.concurrent.Executor;
     30 
     31 /**
     32  * @hide
     33  * MediaPlaylistAgent is the abstract class an application needs to derive from to pass an object
     34  * to a MediaSession2 that will override default playlist handling behaviors. It contains a set of
     35  * notify methods to signal MediaSession2 that playlist-related state has changed.
     36  * <p>
     37  * Playlists are composed of one or multiple {@link MediaItem2} instances, which combine metadata
     38  * and data sources (as {@link DataSourceDesc})
     39  * Used by {@link MediaSession2} and {@link MediaController2}.
     40  */
     41 // This class only includes methods that contain {@link MediaItem2}.
     42 public abstract class MediaPlaylistAgent {
     43     /**
     44      * @hide
     45      */
     46     @IntDef({REPEAT_MODE_NONE, REPEAT_MODE_ONE, REPEAT_MODE_ALL,
     47             REPEAT_MODE_GROUP})
     48     @Retention(RetentionPolicy.SOURCE)
     49     public @interface RepeatMode {}
     50 
     51     /**
     52      * Playback will be stopped at the end of the playing media list.
     53      */
     54     public static final int REPEAT_MODE_NONE = 0;
     55 
     56     /**
     57      * Playback of the current playing media item will be repeated.
     58      */
     59     public static final int REPEAT_MODE_ONE = 1;
     60 
     61     /**
     62      * Playing media list will be repeated.
     63      */
     64     public static final int REPEAT_MODE_ALL = 2;
     65 
     66     /**
     67      * Playback of the playing media group will be repeated.
     68      * A group is a logical block of media items which is specified in the section 5.7 of the
     69      * Bluetooth AVRCP 1.6. An example of a group is the playlist.
     70      */
     71     public static final int REPEAT_MODE_GROUP = 3;
     72 
     73     /**
     74      * @hide
     75      */
     76     @IntDef({SHUFFLE_MODE_NONE, SHUFFLE_MODE_ALL, SHUFFLE_MODE_GROUP})
     77     @Retention(RetentionPolicy.SOURCE)
     78     public @interface ShuffleMode {}
     79 
     80     /**
     81      * Media list will be played in order.
     82      */
     83     public static final int SHUFFLE_MODE_NONE = 0;
     84 
     85     /**
     86      * Media list will be played in shuffled order.
     87      */
     88     public static final int SHUFFLE_MODE_ALL = 1;
     89 
     90     /**
     91      * Media group will be played in shuffled order.
     92      * A group is a logical block of media items which is specified in the section 5.7 of the
     93      * Bluetooth AVRCP 1.6. An example of a group is the playlist.
     94      */
     95     public static final int SHUFFLE_MODE_GROUP = 2;
     96 
     97     private final MediaPlaylistAgentProvider mProvider;
     98 
     99     /**
    100      * A callback class to receive notifications for events on the media player. See
    101      * {@link MediaPlaylistAgent#registerPlaylistEventCallback(Executor, PlaylistEventCallback)}
    102      * to register this callback.
    103      */
    104     public static abstract class PlaylistEventCallback {
    105         /**
    106          * Called when a playlist is changed.
    107          *
    108          * @param playlistAgent playlist agent for this event
    109          * @param list new playlist
    110          * @param metadata new metadata
    111          */
    112         public void onPlaylistChanged(@NonNull MediaPlaylistAgent playlistAgent,
    113                 @NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata) { }
    114 
    115         /**
    116          * Called when a playlist metadata is changed.
    117          *
    118          * @param playlistAgent playlist agent for this event
    119          * @param metadata new metadata
    120          */
    121         public void onPlaylistMetadataChanged(@NonNull MediaPlaylistAgent playlistAgent,
    122                 @Nullable MediaMetadata2 metadata) { }
    123 
    124         /**
    125          * Called when the shuffle mode is changed.
    126          *
    127          * @param playlistAgent playlist agent for this event
    128          * @param shuffleMode repeat mode
    129          * @see #SHUFFLE_MODE_NONE
    130          * @see #SHUFFLE_MODE_ALL
    131          * @see #SHUFFLE_MODE_GROUP
    132          */
    133         public void onShuffleModeChanged(@NonNull MediaPlaylistAgent playlistAgent,
    134                 @ShuffleMode int shuffleMode) { }
    135 
    136         /**
    137          * Called when the repeat mode is changed.
    138          *
    139          * @param playlistAgent playlist agent for this event
    140          * @param repeatMode repeat mode
    141          * @see #REPEAT_MODE_NONE
    142          * @see #REPEAT_MODE_ONE
    143          * @see #REPEAT_MODE_ALL
    144          * @see #REPEAT_MODE_GROUP
    145          */
    146         public void onRepeatModeChanged(@NonNull MediaPlaylistAgent playlistAgent,
    147                 @RepeatMode int repeatMode) { }
    148     }
    149 
    150     public MediaPlaylistAgent() {
    151         mProvider = ApiLoader.getProvider().createMediaPlaylistAgent(this);
    152     }
    153 
    154     /**
    155      * Register {@link PlaylistEventCallback} to listen changes in the underlying
    156      * {@link MediaPlaylistAgent}.
    157      *
    158      * @param executor a callback Executor
    159      * @param callback a PlaylistEventCallback
    160      * @throws IllegalArgumentException if executor or callback is {@code null}.
    161      */
    162     public final void registerPlaylistEventCallback(
    163             @NonNull @CallbackExecutor Executor executor, @NonNull PlaylistEventCallback callback) {
    164         mProvider.registerPlaylistEventCallback_impl(executor, callback);
    165     }
    166 
    167     /**
    168      * Unregister the previously registered {@link PlaylistEventCallback}.
    169      *
    170      * @param callback the callback to be removed
    171      * @throws IllegalArgumentException if the callback is {@code null}.
    172      */
    173     public final void unregisterPlaylistEventCallback(@NonNull PlaylistEventCallback callback) {
    174         mProvider.unregisterPlaylistEventCallback_impl(callback);
    175     }
    176 
    177     public final void notifyPlaylistChanged() {
    178         mProvider.notifyPlaylistChanged_impl();
    179     }
    180 
    181     public final void notifyPlaylistMetadataChanged() {
    182         mProvider.notifyPlaylistMetadataChanged_impl();
    183     }
    184 
    185     public final void notifyShuffleModeChanged() {
    186         mProvider.notifyShuffleModeChanged_impl();
    187     }
    188 
    189     public final void notifyRepeatModeChanged() {
    190         mProvider.notifyRepeatModeChanged_impl();
    191     }
    192 
    193     /**
    194      * Returns the playlist
    195      *
    196      * @return playlist, or null if none is set.
    197      */
    198     public @Nullable List<MediaItem2> getPlaylist() {
    199         return mProvider.getPlaylist_impl();
    200     }
    201 
    202     /**
    203      * Sets the playlist.
    204      *
    205      * @param list playlist
    206      * @param metadata metadata of the playlist
    207      */
    208     public void setPlaylist(@NonNull List<MediaItem2> list, @Nullable MediaMetadata2 metadata) {
    209         mProvider.setPlaylist_impl(list, metadata);
    210     }
    211 
    212     /**
    213      * Returns the playlist metadata
    214      *
    215      * @return metadata metadata of the playlist, or null if none is set
    216      */
    217     public @Nullable MediaMetadata2 getPlaylistMetadata() {
    218         return mProvider.getPlaylistMetadata_impl();
    219     }
    220 
    221     /**
    222      * Updates the playlist metadata
    223      *
    224      * @param metadata metadata of the playlist
    225      */
    226     public void updatePlaylistMetadata(@Nullable MediaMetadata2 metadata) {
    227         mProvider.updatePlaylistMetadata_impl(metadata);
    228     }
    229 
    230     /**
    231      * Adds the media item to the playlist at position index. Index equals or greater than
    232      * the current playlist size will add the item at the end of the playlist.
    233      * <p>
    234      * This will not change the currently playing media item.
    235      * If index is less than or equal to the current index of the playlist,
    236      * the current index of the playlist will be incremented correspondingly.
    237      *
    238      * @param index the index you want to add
    239      * @param item the media item you want to add
    240      */
    241     public void addPlaylistItem(int index, @NonNull MediaItem2 item) {
    242         mProvider.addPlaylistItem_impl(index, item);
    243     }
    244 
    245     /**
    246      * Removes the media item from the playlist
    247      *
    248      * @param item media item to remove
    249      */
    250     public void removePlaylistItem(@NonNull MediaItem2 item) {
    251         mProvider.removePlaylistItem_impl(item);
    252     }
    253 
    254     /**
    255      * Replace the media item at index in the playlist. This can be also used to update metadata of
    256      * an item.
    257      *
    258      * @param index the index of the item to replace
    259      * @param item the new item
    260      */
    261     public void replacePlaylistItem(int index, @NonNull MediaItem2 item) {
    262         mProvider.replacePlaylistItem_impl(index, item);
    263     }
    264 
    265     /**
    266      * Skips to the the media item, and plays from it.
    267      *
    268      * @param item media item to start playing from
    269      */
    270     public void skipToPlaylistItem(@NonNull MediaItem2 item) {
    271         mProvider.skipToPlaylistItem_impl(item);
    272     }
    273 
    274     /**
    275      * Skips to the previous item in the playlist.
    276      */
    277     public void skipToPreviousItem() {
    278         mProvider.skipToPreviousItem_impl();
    279     }
    280 
    281     /**
    282      * Skips to the next item in the playlist.
    283      */
    284     public void skipToNextItem() {
    285         mProvider.skipToNextItem_impl();
    286     }
    287 
    288     /**
    289      * Gets the repeat mode
    290      *
    291      * @return repeat mode
    292      * @see #REPEAT_MODE_NONE
    293      * @see #REPEAT_MODE_ONE
    294      * @see #REPEAT_MODE_ALL
    295      * @see #REPEAT_MODE_GROUP
    296      */
    297     public @RepeatMode int getRepeatMode() {
    298         return mProvider.getRepeatMode_impl();
    299     }
    300 
    301     /**
    302      * Sets the repeat mode
    303      *
    304      * @param repeatMode repeat mode
    305      * @see #REPEAT_MODE_NONE
    306      * @see #REPEAT_MODE_ONE
    307      * @see #REPEAT_MODE_ALL
    308      * @see #REPEAT_MODE_GROUP
    309      */
    310     public void setRepeatMode(@RepeatMode int repeatMode) {
    311         mProvider.setRepeatMode_impl(repeatMode);
    312     }
    313 
    314     /**
    315      * Gets the shuffle mode
    316      *
    317      * @return The shuffle mode
    318      * @see #SHUFFLE_MODE_NONE
    319      * @see #SHUFFLE_MODE_ALL
    320      * @see #SHUFFLE_MODE_GROUP
    321      */
    322     public @ShuffleMode int getShuffleMode() {
    323         return mProvider.getShuffleMode_impl();
    324     }
    325 
    326     /**
    327      * Sets the shuffle mode
    328      *
    329      * @param shuffleMode The shuffle mode
    330      * @see #SHUFFLE_MODE_NONE
    331      * @see #SHUFFLE_MODE_ALL
    332      * @see #SHUFFLE_MODE_GROUP
    333      */
    334     public void setShuffleMode(@ShuffleMode int shuffleMode) {
    335         mProvider.setShuffleMode_impl(shuffleMode);
    336     }
    337 
    338     /**
    339      * Called by {@link MediaSession2} when it wants to translate {@link DataSourceDesc} from the
    340      * {@link MediaPlayerBase.PlayerEventCallback} to the {@link MediaItem2}. Override this method
    341      * if you want to create {@link DataSourceDesc}s dynamically, instead of specifying them with
    342      * {@link #setPlaylist(List, MediaMetadata2)}.
    343      * <p>
    344      * Session would throw an exception if this returns {@code null} for {@param dsd} from the
    345      * {@link MediaPlayerBase.PlayerEventCallback}.
    346      * <p>
    347      * Default implementation calls the {@link #getPlaylist()} and searches the {@link MediaItem2}
    348      * with the {@param dsd}.
    349      *
    350      * @param dsd The dsd to query.
    351      * @return A {@link MediaItem2} object in the playlist that matches given {@code dsd}.
    352      * @throws IllegalArgumentException if {@code dsd} is null
    353      */
    354     public @Nullable MediaItem2 getMediaItem(@NonNull DataSourceDesc dsd) {
    355         return mProvider.getMediaItem_impl(dsd);
    356     }
    357 }
    358