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 17package android.support.v4.media.session; 18 19import android.app.PendingIntent; 20import android.content.Context; 21import android.content.Intent; 22import android.media.AudioAttributes; 23import android.media.MediaDescription; 24import android.media.MediaMetadata; 25import android.media.Rating; 26import android.media.VolumeProvider; 27import android.media.session.MediaSession; 28import android.media.session.PlaybackState; 29import android.os.Bundle; 30import android.os.Handler; 31import android.os.Parcelable; 32import android.os.ResultReceiver; 33import android.support.annotation.RequiresApi; 34import android.util.Log; 35 36import java.lang.reflect.Field; 37import java.util.ArrayList; 38import java.util.List; 39 40@RequiresApi(21) 41class MediaSessionCompatApi21 { 42 static final String TAG = "MediaSessionCompatApi21"; 43 44 public static Object createSession(Context context, String tag) { 45 return new MediaSession(context, tag); 46 } 47 48 public static Object verifySession(Object mediaSession) { 49 if (mediaSession instanceof MediaSession) { 50 return mediaSession; 51 } 52 throw new IllegalArgumentException("mediaSession is not a valid MediaSession object"); 53 } 54 55 public static Object verifyToken(Object token) { 56 if (token instanceof MediaSession.Token) { 57 return token; 58 } 59 throw new IllegalArgumentException("token is not a valid MediaSession.Token object"); 60 } 61 62 public static Object createCallback(Callback callback) { 63 return new CallbackProxy<Callback>(callback); 64 } 65 66 public static void setCallback(Object sessionObj, Object callbackObj, Handler handler) { 67 ((MediaSession) sessionObj).setCallback((MediaSession.Callback) callbackObj, handler); 68 } 69 70 public static void setFlags(Object sessionObj, int flags) { 71 ((MediaSession)sessionObj).setFlags(flags); 72 } 73 74 public static void setPlaybackToLocal(Object sessionObj, int stream) { 75 // TODO update APIs to use support version of AudioAttributes 76 AudioAttributes.Builder bob = new AudioAttributes.Builder(); 77 bob.setLegacyStreamType(stream); 78 ((MediaSession) sessionObj).setPlaybackToLocal(bob.build()); 79 } 80 81 public static void setPlaybackToRemote(Object sessionObj, Object volumeProviderObj) { 82 ((MediaSession)sessionObj).setPlaybackToRemote((VolumeProvider)volumeProviderObj); 83 } 84 85 public static void setActive(Object sessionObj, boolean active) { 86 ((MediaSession)sessionObj).setActive(active); 87 } 88 89 public static boolean isActive(Object sessionObj) { 90 return ((MediaSession)sessionObj).isActive(); 91 } 92 93 public static void sendSessionEvent(Object sessionObj, String event, Bundle extras) { 94 ((MediaSession)sessionObj).sendSessionEvent(event, extras); 95 } 96 97 public static void release(Object sessionObj) { 98 ((MediaSession)sessionObj).release(); 99 } 100 101 public static Parcelable getSessionToken(Object sessionObj) { 102 return ((MediaSession)sessionObj).getSessionToken(); 103 } 104 105 public static void setPlaybackState(Object sessionObj, Object stateObj) { 106 ((MediaSession)sessionObj).setPlaybackState((PlaybackState)stateObj); 107 } 108 109 public static void setMetadata(Object sessionObj, Object metadataObj) { 110 ((MediaSession)sessionObj).setMetadata((MediaMetadata)metadataObj); 111 } 112 113 public static void setSessionActivity(Object sessionObj, PendingIntent pi) { 114 ((MediaSession) sessionObj).setSessionActivity(pi); 115 } 116 117 public static void setMediaButtonReceiver(Object sessionObj, PendingIntent pi) { 118 ((MediaSession) sessionObj).setMediaButtonReceiver(pi); 119 } 120 121 public static void setQueue(Object sessionObj, List<Object> queueObjs) { 122 if (queueObjs == null) { 123 ((MediaSession) sessionObj).setQueue(null); 124 return; 125 } 126 ArrayList<MediaSession.QueueItem> queue = new ArrayList<MediaSession.QueueItem>(); 127 for (Object itemObj : queueObjs) { 128 queue.add((MediaSession.QueueItem) itemObj); 129 } 130 ((MediaSession) sessionObj).setQueue(queue); 131 } 132 133 public static void setQueueTitle(Object sessionObj, CharSequence title) { 134 ((MediaSession) sessionObj).setQueueTitle(title); 135 } 136 137 public static void setExtras(Object sessionObj, Bundle extras) { 138 ((MediaSession) sessionObj).setExtras(extras); 139 } 140 141 public static boolean hasCallback(Object sessionObj) { 142 Field callbackField = null; 143 try { 144 callbackField = sessionObj.getClass().getDeclaredField("mCallback"); 145 if (callbackField != null) { 146 callbackField.setAccessible(true); 147 return callbackField.get(sessionObj) != null; 148 } 149 } catch (NoSuchFieldException | IllegalAccessException e) { 150 Log.w(TAG, "Failed to get mCallback object."); 151 } 152 return false; 153 } 154 155 interface Callback { 156 void onCommand(String command, Bundle extras, ResultReceiver cb); 157 boolean onMediaButtonEvent(Intent mediaButtonIntent); 158 void onPlay(); 159 void onPlayFromMediaId(String mediaId, Bundle extras); 160 void onPlayFromSearch(String search, Bundle extras); 161 void onSkipToQueueItem(long id); 162 void onPause(); 163 void onSkipToNext(); 164 void onSkipToPrevious(); 165 void onFastForward(); 166 void onRewind(); 167 void onStop(); 168 void onSeekTo(long position); 169 void onSetRating(Object ratingObject); 170 void onCustomAction(String action, Bundle extras); 171 } 172 173 static class CallbackProxy<T extends Callback> extends MediaSession.Callback { 174 protected final T mCallback; 175 176 public CallbackProxy(T callback) { 177 mCallback = callback; 178 } 179 180 @Override 181 public void onCommand(String command, Bundle args, ResultReceiver cb) { 182 mCallback.onCommand(command, args, cb); 183 } 184 185 @Override 186 public boolean onMediaButtonEvent(Intent mediaButtonIntent) { 187 return mCallback.onMediaButtonEvent(mediaButtonIntent) 188 || super.onMediaButtonEvent(mediaButtonIntent); 189 } 190 191 @Override 192 public void onPlay() { 193 mCallback.onPlay(); 194 } 195 196 @Override 197 public void onPlayFromMediaId(String mediaId, Bundle extras) { 198 mCallback.onPlayFromMediaId(mediaId, extras); 199 } 200 201 @Override 202 public void onPlayFromSearch(String search, Bundle extras) { 203 mCallback.onPlayFromSearch(search, extras); 204 } 205 206 @Override 207 public void onSkipToQueueItem(long id) { 208 mCallback.onSkipToQueueItem(id); 209 } 210 211 @Override 212 public void onPause() { 213 mCallback.onPause(); 214 } 215 216 @Override 217 public void onSkipToNext() { 218 mCallback.onSkipToNext(); 219 } 220 221 @Override 222 public void onSkipToPrevious() { 223 mCallback.onSkipToPrevious(); 224 } 225 226 @Override 227 public void onFastForward() { 228 mCallback.onFastForward(); 229 } 230 231 @Override 232 public void onRewind() { 233 mCallback.onRewind(); 234 } 235 236 @Override 237 public void onStop() { 238 mCallback.onStop(); 239 } 240 241 @Override 242 public void onSeekTo(long pos) { 243 mCallback.onSeekTo(pos); 244 } 245 246 @Override 247 public void onSetRating(Rating rating) { 248 mCallback.onSetRating(rating); 249 } 250 251 @Override 252 public void onCustomAction(String action, Bundle extras) { 253 mCallback.onCustomAction(action, extras); 254 } 255 } 256 257 static class QueueItem { 258 259 public static Object createItem(Object mediaDescription, long id) { 260 return new MediaSession.QueueItem((MediaDescription) mediaDescription, id); 261 } 262 263 public static Object getDescription(Object queueItem) { 264 return ((MediaSession.QueueItem) queueItem).getDescription(); 265 } 266 267 public static long getQueueId(Object queueItem) { 268 return ((MediaSession.QueueItem) queueItem).getQueueId(); 269 } 270 } 271} 272