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 */ 16package android.support.v4.media.session; 17 18import android.app.PendingIntent; 19import android.content.Context; 20import android.content.Intent; 21import android.graphics.Bitmap; 22import android.media.AudioManager; 23import android.media.MediaMetadataRetriever; 24import android.media.RemoteControlClient; 25import android.os.Bundle; 26import android.os.ResultReceiver; 27 28class MediaSessionCompatApi14 { 29 /***** RemoteControlClient States, we only need none as the others were public *******/ 30 final static int RCC_PLAYSTATE_NONE = 0; 31 32 /***** MediaSession States *******/ 33 final static int STATE_NONE = 0; 34 final static int STATE_STOPPED = 1; 35 final static int STATE_PAUSED = 2; 36 final static int STATE_PLAYING = 3; 37 final static int STATE_FAST_FORWARDING = 4; 38 final static int STATE_REWINDING = 5; 39 final static int STATE_BUFFERING = 6; 40 final static int STATE_ERROR = 7; 41 final static int STATE_CONNECTING = 8; 42 final static int STATE_SKIPPING_TO_PREVIOUS = 9; 43 final static int STATE_SKIPPING_TO_NEXT = 10; 44 final static int STATE_SKIPPING_TO_QUEUE_ITEM = 11; 45 46 /***** PlaybackState actions *****/ 47 private static final long ACTION_STOP = 1 << 0; 48 private static final long ACTION_PAUSE = 1 << 1; 49 private static final long ACTION_PLAY = 1 << 2; 50 private static final long ACTION_REWIND = 1 << 3; 51 private static final long ACTION_SKIP_TO_PREVIOUS = 1 << 4; 52 private static final long ACTION_SKIP_TO_NEXT = 1 << 5; 53 private static final long ACTION_FAST_FORWARD = 1 << 6; 54 private static final long ACTION_PLAY_PAUSE = 1 << 9; 55 56 /***** MediaMetadata keys ********/ 57 private static final String METADATA_KEY_ART = "android.media.metadata.ART"; 58 private static final String METADATA_KEY_ALBUM_ART = "android.media.metadata.ALBUM_ART"; 59 private static final String METADATA_KEY_TITLE = "android.media.metadata.TITLE"; 60 private static final String METADATA_KEY_ARTIST = "android.media.metadata.ARTIST"; 61 private static final String METADATA_KEY_DURATION = "android.media.metadata.DURATION"; 62 private static final String METADATA_KEY_ALBUM = "android.media.metadata.ALBUM"; 63 private static final String METADATA_KEY_AUTHOR = "android.media.metadata.AUTHOR"; 64 private static final String METADATA_KEY_WRITER = "android.media.metadata.WRITER"; 65 private static final String METADATA_KEY_COMPOSER = "android.media.metadata.COMPOSER"; 66 private static final String METADATA_KEY_COMPILATION = "android.media.metadata.COMPILATION"; 67 private static final String METADATA_KEY_DATE = "android.media.metadata.DATE"; 68 private static final String METADATA_KEY_GENRE = "android.media.metadata.GENRE"; 69 private static final String METADATA_KEY_TRACK_NUMBER = "android.media.metadata.TRACK_NUMBER"; 70 private static final String METADATA_KEY_DISC_NUMBER = "android.media.metadata.DISC_NUMBER"; 71 private static final String METADATA_KEY_ALBUM_ARTIST = "android.media.metadata.ALBUM_ARTIST"; 72 73 public static Object createRemoteControlClient(PendingIntent mbIntent) { 74 return new RemoteControlClient(mbIntent); 75 } 76 77 public static void setState(Object rccObj, int state) { 78 ((RemoteControlClient) rccObj).setPlaybackState(getRccStateFromState(state)); 79 } 80 81 public static void setTransportControlFlags(Object rccObj, long actions) { 82 ((RemoteControlClient) rccObj).setTransportControlFlags( 83 getRccTransportControlFlagsFromActions(actions)); 84 } 85 86 public static void setMetadata(Object rccObj, Bundle metadata) { 87 RemoteControlClient.MetadataEditor editor = ((RemoteControlClient) rccObj).editMetadata( 88 true); 89 buildOldMetadata(metadata, editor); 90 editor.apply(); 91 } 92 93 public static void registerRemoteControlClient(Context context, Object rccObj) { 94 AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 95 am.registerRemoteControlClient((RemoteControlClient) rccObj); 96 } 97 98 public static void unregisterRemoteControlClient(Context context, Object rccObj) { 99 AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 100 am.unregisterRemoteControlClient((RemoteControlClient) rccObj); 101 } 102 103 static int getRccStateFromState(int state) { 104 switch (state) { 105 case STATE_CONNECTING: 106 case STATE_BUFFERING: 107 return RemoteControlClient.PLAYSTATE_BUFFERING; 108 case STATE_ERROR: 109 return RemoteControlClient.PLAYSTATE_ERROR; 110 case STATE_FAST_FORWARDING: 111 return RemoteControlClient.PLAYSTATE_FAST_FORWARDING; 112 case STATE_NONE: 113 return RCC_PLAYSTATE_NONE; 114 case STATE_PAUSED: 115 return RemoteControlClient.PLAYSTATE_PAUSED; 116 case STATE_PLAYING: 117 return RemoteControlClient.PLAYSTATE_PLAYING; 118 case STATE_REWINDING: 119 return RemoteControlClient.PLAYSTATE_REWINDING; 120 case STATE_SKIPPING_TO_PREVIOUS: 121 return RemoteControlClient.PLAYSTATE_SKIPPING_BACKWARDS; 122 case STATE_SKIPPING_TO_NEXT: 123 case STATE_SKIPPING_TO_QUEUE_ITEM: 124 return RemoteControlClient.PLAYSTATE_SKIPPING_FORWARDS; 125 case STATE_STOPPED: 126 return RemoteControlClient.PLAYSTATE_STOPPED; 127 default: 128 return -1; 129 } 130 } 131 132 static int getRccTransportControlFlagsFromActions(long actions) { 133 int transportControlFlags = 0; 134 if ((actions & ACTION_STOP) != 0) { 135 transportControlFlags |= RemoteControlClient.FLAG_KEY_MEDIA_STOP; 136 } 137 if ((actions & ACTION_PAUSE) != 0) { 138 transportControlFlags |= RemoteControlClient.FLAG_KEY_MEDIA_PAUSE; 139 } 140 if ((actions & ACTION_PLAY) != 0) { 141 transportControlFlags |= RemoteControlClient.FLAG_KEY_MEDIA_PLAY; 142 } 143 if ((actions & ACTION_REWIND) != 0) { 144 transportControlFlags |= RemoteControlClient.FLAG_KEY_MEDIA_REWIND; 145 } 146 if ((actions & ACTION_SKIP_TO_PREVIOUS) != 0) { 147 transportControlFlags |= RemoteControlClient.FLAG_KEY_MEDIA_PREVIOUS; 148 } 149 if ((actions & ACTION_SKIP_TO_NEXT) != 0) { 150 transportControlFlags |= RemoteControlClient.FLAG_KEY_MEDIA_NEXT; 151 } 152 if ((actions & ACTION_FAST_FORWARD) != 0) { 153 transportControlFlags |= RemoteControlClient.FLAG_KEY_MEDIA_FAST_FORWARD; 154 } 155 if ((actions & ACTION_PLAY_PAUSE) != 0) { 156 transportControlFlags |= RemoteControlClient.FLAG_KEY_MEDIA_PLAY_PAUSE; 157 } 158 return transportControlFlags; 159 } 160 161 static void buildOldMetadata(Bundle metadata, RemoteControlClient.MetadataEditor editor) { 162 if (metadata == null) { 163 return; 164 } 165 if (metadata.containsKey(METADATA_KEY_ART)) { 166 Bitmap art = metadata.getParcelable(METADATA_KEY_ART); 167 editor.putBitmap(RemoteControlClient.MetadataEditor.BITMAP_KEY_ARTWORK, art); 168 } else if (metadata.containsKey(METADATA_KEY_ALBUM_ART)) { 169 // Fall back to album art if the track art wasn't available 170 Bitmap art = metadata.getParcelable(METADATA_KEY_ALBUM_ART); 171 editor.putBitmap(RemoteControlClient.MetadataEditor.BITMAP_KEY_ARTWORK, art); 172 } 173 if (metadata.containsKey(METADATA_KEY_ALBUM)) { 174 editor.putString(MediaMetadataRetriever.METADATA_KEY_ALBUM, 175 metadata.getString(METADATA_KEY_ALBUM)); 176 } 177 if (metadata.containsKey(METADATA_KEY_ALBUM_ARTIST)) { 178 editor.putString(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST, 179 metadata.getString(METADATA_KEY_ALBUM_ARTIST)); 180 } 181 if (metadata.containsKey(METADATA_KEY_ARTIST)) { 182 editor.putString(MediaMetadataRetriever.METADATA_KEY_ARTIST, 183 metadata.getString(METADATA_KEY_ARTIST)); 184 } 185 if (metadata.containsKey(METADATA_KEY_AUTHOR)) { 186 editor.putString(MediaMetadataRetriever.METADATA_KEY_AUTHOR, 187 metadata.getString(METADATA_KEY_AUTHOR)); 188 } 189 if (metadata.containsKey(METADATA_KEY_COMPILATION)) { 190 editor.putString(MediaMetadataRetriever.METADATA_KEY_COMPILATION, 191 metadata.getString(METADATA_KEY_COMPILATION)); 192 } 193 if (metadata.containsKey(METADATA_KEY_COMPOSER)) { 194 editor.putString(MediaMetadataRetriever.METADATA_KEY_COMPOSER, 195 metadata.getString(METADATA_KEY_COMPOSER)); 196 } 197 if (metadata.containsKey(METADATA_KEY_DATE)) { 198 editor.putString(MediaMetadataRetriever.METADATA_KEY_DATE, 199 metadata.getString(METADATA_KEY_DATE)); 200 } 201 if (metadata.containsKey(METADATA_KEY_DISC_NUMBER)) { 202 editor.putLong(MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER, 203 metadata.getLong(METADATA_KEY_DISC_NUMBER)); 204 } 205 if (metadata.containsKey(METADATA_KEY_DURATION)) { 206 editor.putLong(MediaMetadataRetriever.METADATA_KEY_DURATION, 207 metadata.getLong(METADATA_KEY_DURATION)); 208 } 209 if (metadata.containsKey(METADATA_KEY_GENRE)) { 210 editor.putString(MediaMetadataRetriever.METADATA_KEY_GENRE, 211 metadata.getString(METADATA_KEY_GENRE)); 212 } 213 if (metadata.containsKey(METADATA_KEY_TITLE)) { 214 editor.putString(MediaMetadataRetriever.METADATA_KEY_TITLE, 215 metadata.getString(METADATA_KEY_TITLE)); 216 } 217 if (metadata.containsKey(METADATA_KEY_TRACK_NUMBER)) { 218 editor.putLong(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER, 219 metadata.getLong(METADATA_KEY_TRACK_NUMBER)); 220 } 221 if (metadata.containsKey(METADATA_KEY_WRITER)) { 222 editor.putString(MediaMetadataRetriever.METADATA_KEY_WRITER, 223 metadata.getString(METADATA_KEY_WRITER)); 224 } 225 } 226} 227