• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
getPlayingQueue( String mediaId, MusicProvider musicProvider)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 
getPlayingQueueFromSearch( String query, MusicProvider musicProvider)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 
getMusicIndexOnQueue(Iterable<MediaSession.QueueItem> queue, String mediaId)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 
getMusicIndexOnQueue(Iterable<MediaSession.QueueItem> queue, long queueId)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 
convertToQueue( Iterable<MediaMetadata> tracks, String... categories)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      */
getRandomQueue(MusicProvider musicProvider)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 
isIndexPlayable(int index, List<MediaSession.QueueItem> queue)162     public static boolean isIndexPlayable(int index, List<MediaSession.QueueItem> queue) {
163         return (queue != null && index >= 0 && index < queue.size());
164     }
165 }
166