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.example.android.mediabrowserservice.utils; 18 19 import android.media.MediaMetadata; 20 import android.media.session.MediaSession; 21 22 import com.example.android.mediabrowserservice.model.MusicProvider; 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.example.android.mediabrowserservice.utils.MediaIDHelper.MEDIA_ID_MUSICS_BY_GENRE; 30 import static com.example.android.mediabrowserservice.utils.MediaIDHelper.MEDIA_ID_MUSICS_BY_SEARCH; 31 32 /** 33 * Utility class to help on queue related tasks. 34 */ 35 public class QueueHelper { 36 37 private static final String TAG = LogHelper.makeLogTag(QueueHelper.class); 38 getPlayingQueue(String mediaId, MusicProvider musicProvider)39 public static List<MediaSession.QueueItem> getPlayingQueue(String mediaId, 40 MusicProvider musicProvider) { 41 42 // extract the browsing hierarchy from the media ID: 43 String[] hierarchy = MediaIDHelper.getHierarchy(mediaId); 44 45 if (hierarchy.length != 2) { 46 LogHelper.e(TAG, "Could not build a playing queue for this mediaId: ", mediaId); 47 return null; 48 } 49 50 String categoryType = hierarchy[0]; 51 String categoryValue = hierarchy[1]; 52 LogHelper.d(TAG, "Creating playing queue for ", categoryType, ", ", categoryValue); 53 54 Iterable<MediaMetadata> tracks = null; 55 // This sample only supports genre and by_search category types. 56 if (categoryType.equals(MEDIA_ID_MUSICS_BY_GENRE)) { 57 tracks = musicProvider.getMusicsByGenre(categoryValue); 58 } else if (categoryType.equals(MEDIA_ID_MUSICS_BY_SEARCH)) { 59 tracks = musicProvider.searchMusic(categoryValue); 60 } 61 62 if (tracks == null) { 63 LogHelper.e(TAG, "Unrecognized category type: ", categoryType, " for mediaId ", mediaId); 64 return null; 65 } 66 67 return convertToQueue(tracks, hierarchy[0], hierarchy[1]); 68 } 69 getPlayingQueueFromSearch(String query, MusicProvider musicProvider)70 public static List<MediaSession.QueueItem> getPlayingQueueFromSearch(String query, 71 MusicProvider musicProvider) { 72 73 LogHelper.d(TAG, "Creating playing queue for musics from search ", query); 74 75 return convertToQueue(musicProvider.searchMusic(query), MEDIA_ID_MUSICS_BY_SEARCH, query); 76 } 77 78 getMusicIndexOnQueue(Iterable<MediaSession.QueueItem> queue, String mediaId)79 public static int getMusicIndexOnQueue(Iterable<MediaSession.QueueItem> queue, 80 String mediaId) { 81 int index = 0; 82 for (MediaSession.QueueItem item : queue) { 83 if (mediaId.equals(item.getDescription().getMediaId())) { 84 return index; 85 } 86 index++; 87 } 88 return -1; 89 } 90 getMusicIndexOnQueue(Iterable<MediaSession.QueueItem> queue, long queueId)91 public static int getMusicIndexOnQueue(Iterable<MediaSession.QueueItem> queue, 92 long queueId) { 93 int index = 0; 94 for (MediaSession.QueueItem item : queue) { 95 if (queueId == item.getQueueId()) { 96 return index; 97 } 98 index++; 99 } 100 return -1; 101 } 102 convertToQueue( Iterable<MediaMetadata> tracks, String... categories)103 private static List<MediaSession.QueueItem> convertToQueue( 104 Iterable<MediaMetadata> tracks, String... categories) { 105 List<MediaSession.QueueItem> queue = new ArrayList<>(); 106 int count = 0; 107 for (MediaMetadata track : tracks) { 108 109 // We create a hierarchy-aware mediaID, so we know what the queue is about by looking 110 // at the QueueItem media IDs. 111 String hierarchyAwareMediaID = MediaIDHelper.createMediaID( 112 track.getDescription().getMediaId(), categories); 113 114 MediaMetadata trackCopy = new MediaMetadata.Builder(track) 115 .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, hierarchyAwareMediaID) 116 .build(); 117 118 // We don't expect queues to change after created, so we use the item index as the 119 // queueId. Any other number unique in the queue would work. 120 MediaSession.QueueItem item = new MediaSession.QueueItem( 121 trackCopy.getDescription(), count++); 122 queue.add(item); 123 } 124 return queue; 125 126 } 127 128 /** 129 * Create a random queue. For simplicity sake, instead of a random queue, we create a 130 * queue using the first genre. 131 * 132 * @param musicProvider the provider used for fetching music. 133 * @return list containing {@link android.media.session.MediaSession.QueueItem}'s 134 */ getRandomQueue(MusicProvider musicProvider)135 public static List<MediaSession.QueueItem> getRandomQueue(MusicProvider musicProvider) { 136 Iterator<String> genres = musicProvider.getGenres().iterator(); 137 if (!genres.hasNext()) { 138 return Collections.emptyList(); 139 } 140 String genre = genres.next(); 141 Iterable<MediaMetadata> tracks = musicProvider.getMusicsByGenre(genre); 142 143 return convertToQueue(tracks, MEDIA_ID_MUSICS_BY_GENRE, genre); 144 } 145 isIndexPlayable(int index, List<MediaSession.QueueItem> queue)146 public static boolean isIndexPlayable(int index, List<MediaSession.QueueItem> queue) { 147 return (queue != null && index >= 0 && index < queue.size()); 148 } 149 } 150