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 android.support.v4.media.session; 18 19 import android.app.Activity; 20 import android.app.PendingIntent; 21 import android.content.Context; 22 import android.media.AudioAttributes; 23 import android.media.AudioManager; 24 import android.media.MediaMetadata; 25 import android.media.Rating; 26 import android.media.session.MediaController; 27 import android.media.session.MediaSession; 28 import android.media.session.PlaybackState; 29 import android.os.Bundle; 30 import android.os.Handler; 31 import android.os.ResultReceiver; 32 import android.support.annotation.RequiresApi; 33 import android.view.KeyEvent; 34 35 import java.util.ArrayList; 36 import java.util.List; 37 38 @RequiresApi(21) 39 class MediaControllerCompatApi21 { fromToken(Context context, Object sessionToken)40 public static Object fromToken(Context context, Object sessionToken) { 41 return new MediaController(context, (MediaSession.Token) sessionToken); 42 } 43 createCallback(Callback callback)44 public static Object createCallback(Callback callback) { 45 return new CallbackProxy<Callback>(callback); 46 } 47 registerCallback(Object controllerObj, Object callbackObj, Handler handler)48 public static void registerCallback(Object controllerObj, Object callbackObj, Handler handler) { 49 ((MediaController) controllerObj).registerCallback( 50 (MediaController.Callback)callbackObj, handler); 51 } 52 unregisterCallback(Object controllerObj, Object callbackObj)53 public static void unregisterCallback(Object controllerObj, Object callbackObj) { 54 ((MediaController) controllerObj) 55 .unregisterCallback((MediaController.Callback) callbackObj); 56 } 57 setMediaController(Activity activity, Object controllerObj)58 public static void setMediaController(Activity activity, Object controllerObj) { 59 activity.setMediaController((MediaController) controllerObj); 60 } 61 getMediaController(Activity activity)62 public static Object getMediaController(Activity activity) { 63 return activity.getMediaController(); 64 } 65 getSessionToken(Object controllerObj)66 public static Object getSessionToken(Object controllerObj) { 67 return ((MediaController) controllerObj).getSessionToken(); 68 } 69 getTransportControls(Object controllerObj)70 public static Object getTransportControls(Object controllerObj) { 71 return ((MediaController)controllerObj).getTransportControls(); 72 } 73 getPlaybackState(Object controllerObj)74 public static Object getPlaybackState(Object controllerObj) { 75 return ((MediaController)controllerObj).getPlaybackState(); 76 } 77 getMetadata(Object controllerObj)78 public static Object getMetadata(Object controllerObj) { 79 return ((MediaController)controllerObj).getMetadata(); 80 } 81 getQueue(Object controllerObj)82 public static List<Object> getQueue(Object controllerObj) { 83 List<MediaSession.QueueItem> queue = ((MediaController) controllerObj).getQueue(); 84 if (queue == null) { 85 return null; 86 } 87 List<Object> queueObjs = new ArrayList<Object>(queue); 88 return queueObjs; 89 } 90 getQueueTitle(Object controllerObj)91 public static CharSequence getQueueTitle(Object controllerObj) { 92 return ((MediaController) controllerObj).getQueueTitle(); 93 } 94 getExtras(Object controllerObj)95 public static Bundle getExtras(Object controllerObj) { 96 return ((MediaController) controllerObj).getExtras(); 97 } 98 getRatingType(Object controllerObj)99 public static int getRatingType(Object controllerObj) { 100 return ((MediaController) controllerObj).getRatingType(); 101 } 102 getFlags(Object controllerObj)103 public static long getFlags(Object controllerObj) { 104 return ((MediaController) controllerObj).getFlags(); 105 } 106 getPlaybackInfo(Object controllerObj)107 public static Object getPlaybackInfo(Object controllerObj) { 108 return ((MediaController) controllerObj).getPlaybackInfo(); 109 } 110 getSessionActivity(Object controllerObj)111 public static PendingIntent getSessionActivity(Object controllerObj) { 112 return ((MediaController) controllerObj).getSessionActivity(); 113 } 114 dispatchMediaButtonEvent(Object controllerObj, KeyEvent event)115 public static boolean dispatchMediaButtonEvent(Object controllerObj, KeyEvent event) { 116 return ((MediaController) controllerObj).dispatchMediaButtonEvent(event); 117 } 118 setVolumeTo(Object controllerObj, int value, int flags)119 public static void setVolumeTo(Object controllerObj, int value, int flags) { 120 ((MediaController) controllerObj).setVolumeTo(value, flags); 121 } 122 adjustVolume(Object controllerObj, int direction, int flags)123 public static void adjustVolume(Object controllerObj, int direction, int flags) { 124 ((MediaController) controllerObj).adjustVolume(direction, flags); 125 } 126 sendCommand(Object controllerObj, String command, Bundle params, ResultReceiver cb)127 public static void sendCommand(Object controllerObj, 128 String command, Bundle params, ResultReceiver cb) { 129 ((MediaController) controllerObj).sendCommand(command, params, cb); 130 } 131 getPackageName(Object controllerObj)132 public static String getPackageName(Object controllerObj) { 133 return ((MediaController) controllerObj).getPackageName(); 134 } 135 136 public static class TransportControls { play(Object controlsObj)137 public static void play(Object controlsObj) { 138 ((MediaController.TransportControls)controlsObj).play(); 139 } 140 pause(Object controlsObj)141 public static void pause(Object controlsObj) { 142 ((MediaController.TransportControls)controlsObj).pause(); 143 } 144 stop(Object controlsObj)145 public static void stop(Object controlsObj) { 146 ((MediaController.TransportControls)controlsObj).stop(); 147 } 148 seekTo(Object controlsObj, long pos)149 public static void seekTo(Object controlsObj, long pos) { 150 ((MediaController.TransportControls)controlsObj).seekTo(pos); 151 } 152 fastForward(Object controlsObj)153 public static void fastForward(Object controlsObj) { 154 ((MediaController.TransportControls)controlsObj).fastForward(); 155 } 156 rewind(Object controlsObj)157 public static void rewind(Object controlsObj) { 158 ((MediaController.TransportControls)controlsObj).rewind(); 159 } 160 skipToNext(Object controlsObj)161 public static void skipToNext(Object controlsObj) { 162 ((MediaController.TransportControls)controlsObj).skipToNext(); 163 } 164 skipToPrevious(Object controlsObj)165 public static void skipToPrevious(Object controlsObj) { 166 ((MediaController.TransportControls)controlsObj).skipToPrevious(); 167 } 168 setRating(Object controlsObj, Object ratingObj)169 public static void setRating(Object controlsObj, Object ratingObj) { 170 ((MediaController.TransportControls)controlsObj).setRating((Rating)ratingObj); 171 } 172 playFromMediaId(Object controlsObj, String mediaId, Bundle extras)173 public static void playFromMediaId(Object controlsObj, String mediaId, Bundle extras) { 174 ((MediaController.TransportControls) controlsObj).playFromMediaId(mediaId, extras); 175 } 176 playFromSearch(Object controlsObj, String query, Bundle extras)177 public static void playFromSearch(Object controlsObj, String query, Bundle extras) { 178 ((MediaController.TransportControls) controlsObj).playFromSearch(query, extras); 179 } 180 skipToQueueItem(Object controlsObj, long id)181 public static void skipToQueueItem(Object controlsObj, long id) { 182 ((MediaController.TransportControls) controlsObj).skipToQueueItem(id); 183 } 184 sendCustomAction(Object controlsObj, String action, Bundle args)185 public static void sendCustomAction(Object controlsObj, String action, Bundle args) { 186 ((MediaController.TransportControls) controlsObj).sendCustomAction(action, args); 187 } 188 } 189 190 public static class PlaybackInfo { getPlaybackType(Object volumeInfoObj)191 public static int getPlaybackType(Object volumeInfoObj) { 192 return ((MediaController.PlaybackInfo)volumeInfoObj).getPlaybackType(); 193 } 194 getAudioAttributes(Object volumeInfoObj)195 public static AudioAttributes getAudioAttributes(Object volumeInfoObj) { 196 return ((MediaController.PlaybackInfo) volumeInfoObj).getAudioAttributes(); 197 } 198 getLegacyAudioStream(Object volumeInfoObj)199 public static int getLegacyAudioStream(Object volumeInfoObj) { 200 AudioAttributes attrs = getAudioAttributes(volumeInfoObj); 201 return toLegacyStreamType(attrs); 202 } 203 getVolumeControl(Object volumeInfoObj)204 public static int getVolumeControl(Object volumeInfoObj) { 205 return ((MediaController.PlaybackInfo)volumeInfoObj).getVolumeControl(); 206 } 207 getMaxVolume(Object volumeInfoObj)208 public static int getMaxVolume(Object volumeInfoObj) { 209 return ((MediaController.PlaybackInfo)volumeInfoObj).getMaxVolume(); 210 } 211 getCurrentVolume(Object volumeInfoObj)212 public static int getCurrentVolume(Object volumeInfoObj) { 213 return ((MediaController.PlaybackInfo)volumeInfoObj).getCurrentVolume(); 214 } 215 216 // This is copied from AudioAttributes.toLegacyStreamType. TODO This 217 // either needs to be kept in sync with that one or toLegacyStreamType 218 // needs to be made public so it can be used by the support lib. 219 private static final int FLAG_SCO = 0x1 << 2; 220 private static final int STREAM_BLUETOOTH_SCO = 6; 221 private static final int STREAM_SYSTEM_ENFORCED = 7; toLegacyStreamType(AudioAttributes aa)222 private static int toLegacyStreamType(AudioAttributes aa) { 223 // flags to stream type mapping 224 if ((aa.getFlags() & AudioAttributes.FLAG_AUDIBILITY_ENFORCED) 225 == AudioAttributes.FLAG_AUDIBILITY_ENFORCED) { 226 return STREAM_SYSTEM_ENFORCED; 227 } 228 if ((aa.getFlags() & FLAG_SCO) == FLAG_SCO) { 229 return STREAM_BLUETOOTH_SCO; 230 } 231 232 // usage to stream type mapping 233 switch (aa.getUsage()) { 234 case AudioAttributes.USAGE_MEDIA: 235 case AudioAttributes.USAGE_GAME: 236 case AudioAttributes.USAGE_ASSISTANCE_ACCESSIBILITY: 237 case AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: 238 return AudioManager.STREAM_MUSIC; 239 case AudioAttributes.USAGE_ASSISTANCE_SONIFICATION: 240 return AudioManager.STREAM_SYSTEM; 241 case AudioAttributes.USAGE_VOICE_COMMUNICATION: 242 return AudioManager.STREAM_VOICE_CALL; 243 case AudioAttributes.USAGE_VOICE_COMMUNICATION_SIGNALLING: 244 return AudioManager.STREAM_DTMF; 245 case AudioAttributes.USAGE_ALARM: 246 return AudioManager.STREAM_ALARM; 247 case AudioAttributes.USAGE_NOTIFICATION_RINGTONE: 248 return AudioManager.STREAM_RING; 249 case AudioAttributes.USAGE_NOTIFICATION: 250 case AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_REQUEST: 251 case AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_INSTANT: 252 case AudioAttributes.USAGE_NOTIFICATION_COMMUNICATION_DELAYED: 253 case AudioAttributes.USAGE_NOTIFICATION_EVENT: 254 return AudioManager.STREAM_NOTIFICATION; 255 case AudioAttributes.USAGE_UNKNOWN: 256 default: 257 return AudioManager.STREAM_MUSIC; 258 } 259 } 260 } 261 262 public static interface Callback { onSessionDestroyed()263 public void onSessionDestroyed(); onSessionEvent(String event, Bundle extras)264 public void onSessionEvent(String event, Bundle extras); onPlaybackStateChanged(Object stateObj)265 public void onPlaybackStateChanged(Object stateObj); onMetadataChanged(Object metadataObj)266 public void onMetadataChanged(Object metadataObj); onQueueChanged(List<?> queue)267 public void onQueueChanged(List<?> queue); onQueueTitleChanged(CharSequence title)268 public void onQueueTitleChanged(CharSequence title); onExtrasChanged(Bundle extras)269 public void onExtrasChanged(Bundle extras); onAudioInfoChanged(int type, int stream, int control, int max, int current)270 public void onAudioInfoChanged(int type, int stream, int control, int max, int current); 271 } 272 273 static class CallbackProxy<T extends Callback> extends MediaController.Callback { 274 protected final T mCallback; 275 CallbackProxy(T callback)276 public CallbackProxy(T callback) { 277 mCallback = callback; 278 } 279 280 @Override onSessionDestroyed()281 public void onSessionDestroyed() { 282 mCallback.onSessionDestroyed(); 283 } 284 285 @Override onSessionEvent(String event, Bundle extras)286 public void onSessionEvent(String event, Bundle extras) { 287 mCallback.onSessionEvent(event, extras); 288 } 289 290 @Override onPlaybackStateChanged(PlaybackState state)291 public void onPlaybackStateChanged(PlaybackState state) { 292 mCallback.onPlaybackStateChanged(state); 293 } 294 295 @Override onMetadataChanged(MediaMetadata metadata)296 public void onMetadataChanged(MediaMetadata metadata) { 297 mCallback.onMetadataChanged(metadata); 298 } 299 300 @Override onQueueChanged(List<MediaSession.QueueItem> queue)301 public void onQueueChanged(List<MediaSession.QueueItem> queue) { 302 mCallback.onQueueChanged(queue); 303 } 304 305 @Override onQueueTitleChanged(CharSequence title)306 public void onQueueTitleChanged(CharSequence title) { 307 mCallback.onQueueTitleChanged(title); 308 } 309 310 @Override onExtrasChanged(Bundle extras)311 public void onExtrasChanged(Bundle extras) { 312 mCallback.onExtrasChanged(extras); 313 } 314 315 @Override onAudioInfoChanged(MediaController.PlaybackInfo info)316 public void onAudioInfoChanged(MediaController.PlaybackInfo info){ 317 mCallback.onAudioInfoChanged(info.getPlaybackType(), 318 PlaybackInfo.getLegacyAudioStream(info), info.getVolumeControl(), 319 info.getMaxVolume(), info.getCurrentVolume()); 320 } 321 } 322 } 323