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