Home | History | Annotate | Download | only in utils
      1 /*
      2  * Copyright (C) 2014 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 com.android.music.utils;
     18 
     19 import android.media.MediaDescription;
     20 import android.media.MediaMetadata;
     21 import android.media.session.MediaSession;
     22 import android.os.Bundle;
     23 
     24 import java.util.ArrayList;
     25 import java.util.Collections;
     26 import java.util.Iterator;
     27 import java.util.List;
     28 
     29 import static com.android.music.utils.MediaIDHelper.MEDIA_ID_MUSICS_BY_ARTIST;
     30 import static com.android.music.utils.MediaIDHelper.MEDIA_ID_MUSICS_BY_SEARCH;
     31 import static com.android.music.utils.MediaIDHelper.MEDIA_ID_MUSICS_BY_SONG;
     32 import static com.android.music.utils.MediaIDHelper.MEDIA_ID_MUSICS_BY_PLAYLIST;
     33 import static com.android.music.utils.MediaIDHelper.MEDIA_ID_MUSICS_BY_ALBUM;
     34 
     35 /**
     36  * Utility class to help on queue related tasks.
     37  */
     38 public class QueueHelper {
     39     private static final String TAG = LogHelper.makeLogTag(QueueHelper.class);
     40 
     41     public static List<MediaSession.QueueItem> getPlayingQueue(
     42             String mediaId, MusicProvider musicProvider) {
     43         // extract the browsing hierarchy from the media ID:
     44         String[] hierarchy = MediaIDHelper.getHierarchy(mediaId);
     45 
     46         if (hierarchy.length != 2) {
     47             LogHelper.e(TAG, "Could not build a playing queue for this mediaId: ", mediaId);
     48             return null;
     49         }
     50 
     51         String categoryType = hierarchy[0];
     52         String categoryValue = hierarchy[1];
     53         LogHelper.d(TAG, "Creating playing queue for ", categoryType, ",  ", categoryValue);
     54 
     55         Iterable<MediaMetadata> tracks = null;
     56         // This sample only supports genre and by_search category types.
     57         switch (categoryType) {
     58             case MEDIA_ID_MUSICS_BY_SONG:
     59                 tracks = musicProvider.getMusicList();
     60                 break;
     61             case MEDIA_ID_MUSICS_BY_ALBUM:
     62                 tracks = musicProvider.getMusicsByAlbum(categoryValue);
     63                 break;
     64             case MEDIA_ID_MUSICS_BY_ARTIST:
     65                 LogHelper.d(TAG, "Not supported");
     66                 break;
     67             default:
     68                 break;
     69         }
     70 
     71         if (tracks == null) {
     72             LogHelper.e(
     73                     TAG, "Unrecognized category type: ", categoryType, " for mediaId ", mediaId);
     74             return null;
     75         }
     76 
     77         return convertToQueue(tracks, hierarchy[0], hierarchy[1]);
     78     }
     79 
     80     public static List<MediaSession.QueueItem> getPlayingQueueFromSearch(
     81             String query, MusicProvider musicProvider) {
     82         LogHelper.d(TAG, "Creating playing queue for musics from search ", query);
     83 
     84         return convertToQueue(musicProvider.searchMusic(query), MEDIA_ID_MUSICS_BY_SEARCH, query);
     85     }
     86 
     87     public static int getMusicIndexOnQueue(Iterable<MediaSession.QueueItem> queue, String mediaId) {
     88         int index = 0;
     89         for (MediaSession.QueueItem item : queue) {
     90             if (mediaId.equals(item.getDescription().getMediaId())) {
     91                 return index;
     92             }
     93             index++;
     94         }
     95         return -1;
     96     }
     97 
     98     public static int getMusicIndexOnQueue(Iterable<MediaSession.QueueItem> queue, long queueId) {
     99         int index = 0;
    100         for (MediaSession.QueueItem item : queue) {
    101             if (queueId == item.getQueueId()) {
    102                 return index;
    103             }
    104             index++;
    105         }
    106         return -1;
    107     }
    108 
    109     private static List<MediaSession.QueueItem> convertToQueue(
    110             Iterable<MediaMetadata> tracks, String... categories) {
    111         List<MediaSession.QueueItem> queue = new ArrayList<>();
    112         int count = 0;
    113         for (MediaMetadata track : tracks) {
    114             // We create a hierarchy-aware mediaID, so we know what the queue is about by looking
    115             // at the QueueItem media IDs.
    116             String hierarchyAwareMediaID =
    117                     MediaIDHelper.createMediaID(track.getDescription().getMediaId(), categories);
    118             long duration = track.getLong(MediaMetadata.METADATA_KEY_DURATION);
    119             MediaDescription.Builder descriptionBuilder = new MediaDescription.Builder();
    120             MediaDescription description = track.getDescription();
    121             Bundle extras = description.getExtras();
    122             if (extras == null) {
    123                 extras = new Bundle();
    124             }
    125             extras.putLong(MediaMetadata.METADATA_KEY_DURATION, duration);
    126             descriptionBuilder.setExtras(extras)
    127                     .setMediaId(hierarchyAwareMediaID)
    128                     .setTitle(description.getTitle())
    129                     .setSubtitle(track.getString(MediaMetadata.METADATA_KEY_ARTIST))
    130                     .setIconBitmap(description.getIconBitmap())
    131                     .setIconUri(description.getIconUri())
    132                     .setMediaUri(description.getMediaUri())
    133                     .setDescription(description.getDescription());
    134 
    135             // We don't expect queues to change after created, so we use the item index as the
    136             // queueId. Any other number unique in the queue would work.
    137             MediaSession.QueueItem item =
    138                     new MediaSession.QueueItem(descriptionBuilder.build(), count++);
    139             queue.add(item);
    140         }
    141         return queue;
    142     }
    143 
    144     /**
    145      * Create a random queue. For simplicity sake, instead of a random queue, we create a
    146      * queue using the first genre.
    147      *
    148      * @param musicProvider the provider used for fetching music.
    149      * @return list containing {@link android.media.session.MediaSession.QueueItem}'s
    150      */
    151     public static List<MediaSession.QueueItem> getRandomQueue(MusicProvider musicProvider) {
    152         Iterator<String> genres = musicProvider.getArtists().iterator();
    153         if (!genres.hasNext()) {
    154             return Collections.emptyList();
    155         }
    156         String genre = genres.next();
    157         Iterable<MediaMetadata> tracks = musicProvider.getMusicsByAlbum(genre);
    158 
    159         return convertToQueue(tracks, MEDIA_ID_MUSICS_BY_ARTIST, genre);
    160     }
    161 
    162     public static boolean isIndexPlayable(int index, List<MediaSession.QueueItem> queue) {
    163         return (queue != null && index >= 0 && index < queue.size());
    164     }
    165 }
    166