1f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik/* 2f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * Copyright (C) 2014 The Android Open Source Project 3f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * 4f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * Licensed under the Apache License, Version 2.0 (the "License"); 5f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * you may not use this file except in compliance with the License. 6f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * You may obtain a copy of the License at 7f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * 8f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * http://www.apache.org/licenses/LICENSE-2.0 9f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * 10f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * Unless required by applicable law or agreed to in writing, software 11f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * distributed under the License is distributed on an "AS IS" BASIS, 12f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * See the License for the specific language governing permissions and 14f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * limitations under the License. 15f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik */ 16f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 17f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErikpackage android.media.session; 18f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 19f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErikimport android.app.PendingIntent; 20f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErikimport android.app.PendingIntent.CanceledException; 216f0e4ddd66fcdcc13944d8970d0b560e2626508bRoboErikimport android.content.ComponentName; 22f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErikimport android.content.Context; 23f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErikimport android.content.Intent; 24a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErikimport android.graphics.Bitmap; 25a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErikimport android.graphics.Canvas; 26a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErikimport android.graphics.Paint; 27a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErikimport android.graphics.RectF; 283c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErikimport android.media.AudioManager; 2973e23e229dd1a2d25687b1c6a63c708665378e41RoboErikimport android.media.MediaMetadata; 3073e23e229dd1a2d25687b1c6a63c708665378e41RoboErikimport android.media.MediaMetadataEditor; 3173e23e229dd1a2d25687b1c6a63c708665378e41RoboErikimport android.media.MediaMetadataRetriever; 32477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErikimport android.media.Rating; 3373e23e229dd1a2d25687b1c6a63c708665378e41RoboErikimport android.os.Bundle; 34f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErikimport android.os.Handler; 35f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErikimport android.os.Looper; 36f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErikimport android.util.ArrayMap; 37f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErikimport android.util.Log; 38f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErikimport android.view.KeyEvent; 39f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 40f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik/** 41f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * Helper for connecting existing APIs up to the new session APIs. This can be 42f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * used by RCC, AudioFocus, etc. to create a single session that translates to 43f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * all those components. 44f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * 45f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik * @hide 46f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik */ 47f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErikpublic class MediaSessionLegacyHelper { 48f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik private static final String TAG = "MediaSessionHelper"; 491dc5ba86655daf1ee2dd7140e7b20c6d488a48d9RoboErik private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 50f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 51f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik private static final Object sLock = new Object(); 52f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik private static MediaSessionLegacyHelper sInstance; 53f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 548b4bffcac996b4083e720310a09d315ca1c4a000RoboErik private Context mContext; 5542ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik private MediaSessionManager mSessionManager; 56f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik private Handler mHandler = new Handler(Looper.getMainLooper()); 57f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik // The legacy APIs use PendingIntents to register/unregister media button 58f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik // receivers and these are associated with RCC. 59e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik private ArrayMap<PendingIntent, SessionHolder> mSessions 60e7880d8eb1903d42e4e2a90c99b58e2240e01e82RoboErik = new ArrayMap<PendingIntent, SessionHolder>(); 61f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 62f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik private MediaSessionLegacyHelper(Context context) { 638b4bffcac996b4083e720310a09d315ca1c4a000RoboErik mContext = context; 6442ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik mSessionManager = (MediaSessionManager) context 65f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik .getSystemService(Context.MEDIA_SESSION_SERVICE); 66f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 67f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 68f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik public static MediaSessionLegacyHelper getHelper(Context context) { 69f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik synchronized (sLock) { 70f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (sInstance == null) { 719b5257c9c99c4cb541d8e8e78fb04f008b1a9091Jean-Michel Trivi sInstance = new MediaSessionLegacyHelper(context.getApplicationContext()); 72f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 73f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 74f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik return sInstance; 75f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 76f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 77a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik public static Bundle getOldMetadata(MediaMetadata metadata, int artworkWidth, 78a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik int artworkHeight) { 79a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik boolean includeArtwork = artworkWidth != -1 && artworkHeight != -1; 8073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik Bundle oldMetadata = new Bundle(); 8173e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM)) { 8273e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ALBUM), 8373e23e229dd1a2d25687b1c6a63c708665378e41RoboErik metadata.getString(MediaMetadata.METADATA_KEY_ALBUM)); 8473e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 85a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik if (includeArtwork && metadata.containsKey(MediaMetadata.METADATA_KEY_ART)) { 86a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik Bitmap art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ART); 8773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK), 88a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik scaleBitmapIfTooBig(art, artworkWidth, artworkHeight)); 89a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik } else if (includeArtwork && metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART)) { 9073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik // Fall back to album art if the track art wasn't available 91a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik Bitmap art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART); 9273e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK), 93a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik scaleBitmapIfTooBig(art, artworkWidth, artworkHeight)); 9473e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 9573e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ARTIST)) { 9673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST), 9773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik metadata.getString(MediaMetadata.METADATA_KEY_ALBUM_ARTIST)); 9873e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 9973e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_ARTIST)) { 10073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ARTIST), 10173e23e229dd1a2d25687b1c6a63c708665378e41RoboErik metadata.getString(MediaMetadata.METADATA_KEY_ARTIST)); 10273e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 10373e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_AUTHOR)) { 10473e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_AUTHOR), 10573e23e229dd1a2d25687b1c6a63c708665378e41RoboErik metadata.getString(MediaMetadata.METADATA_KEY_AUTHOR)); 10673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 10773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_COMPILATION)) { 10873e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_COMPILATION), 10973e23e229dd1a2d25687b1c6a63c708665378e41RoboErik metadata.getString(MediaMetadata.METADATA_KEY_COMPILATION)); 11073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 11173e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_COMPOSER)) { 11273e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_COMPOSER), 11373e23e229dd1a2d25687b1c6a63c708665378e41RoboErik metadata.getString(MediaMetadata.METADATA_KEY_COMPOSER)); 11473e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 11573e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_DATE)) { 11673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DATE), 11773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik metadata.getString(MediaMetadata.METADATA_KEY_DATE)); 11873e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 11973e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_DISC_NUMBER)) { 12073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER), 12173e23e229dd1a2d25687b1c6a63c708665378e41RoboErik metadata.getLong(MediaMetadata.METADATA_KEY_DISC_NUMBER)); 12273e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 12373e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) { 12473e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DURATION), 12573e23e229dd1a2d25687b1c6a63c708665378e41RoboErik metadata.getLong(MediaMetadata.METADATA_KEY_DURATION)); 12673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 12773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_GENRE)) { 12873e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_GENRE), 12973e23e229dd1a2d25687b1c6a63c708665378e41RoboErik metadata.getString(MediaMetadata.METADATA_KEY_GENRE)); 13073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 13173e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_NUM_TRACKS)) { 13273e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS), 13373e23e229dd1a2d25687b1c6a63c708665378e41RoboErik metadata.getLong(MediaMetadata.METADATA_KEY_NUM_TRACKS)); 13473e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 13573e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_RATING)) { 13673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.RATING_KEY_BY_OTHERS), 13773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik metadata.getRating(MediaMetadata.METADATA_KEY_RATING)); 13873e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 13973e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_USER_RATING)) { 14073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER), 14173e23e229dd1a2d25687b1c6a63c708665378e41RoboErik metadata.getRating(MediaMetadata.METADATA_KEY_USER_RATING)); 14273e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 14373e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_TITLE)) { 14473e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_TITLE), 14573e23e229dd1a2d25687b1c6a63c708665378e41RoboErik metadata.getString(MediaMetadata.METADATA_KEY_TITLE)); 14673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 14773e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_TRACK_NUMBER)) { 14873e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putLong( 14973e23e229dd1a2d25687b1c6a63c708665378e41RoboErik String.valueOf(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER), 15073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik metadata.getLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER)); 15173e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 15273e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_WRITER)) { 15373e23e229dd1a2d25687b1c6a63c708665378e41RoboErik oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_WRITER), 15473e23e229dd1a2d25687b1c6a63c708665378e41RoboErik metadata.getString(MediaMetadata.METADATA_KEY_WRITER)); 15573e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 15673e23e229dd1a2d25687b1c6a63c708665378e41RoboErik if (metadata.containsKey(MediaMetadata.METADATA_KEY_YEAR)) { 157c9763d766c72c32683d2afc10e4eafff64690a24Insun Kang oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_YEAR), 158c9763d766c72c32683d2afc10e4eafff64690a24Insun Kang metadata.getLong(MediaMetadata.METADATA_KEY_YEAR)); 15973e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 16073e23e229dd1a2d25687b1c6a63c708665378e41RoboErik return oldMetadata; 16173e23e229dd1a2d25687b1c6a63c708665378e41RoboErik } 16273e23e229dd1a2d25687b1c6a63c708665378e41RoboErik 16342ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik public MediaSession getSession(PendingIntent pi) { 164f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik SessionHolder holder = mSessions.get(pi); 165f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik return holder == null ? null : holder.mSession; 166f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 167f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 1688a2cfc309ab9126e90022916967c65a793c034f0RoboErik public void sendMediaButtonEvent(KeyEvent keyEvent, boolean needWakeLock) { 1693c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik if (keyEvent == null) { 1703c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik Log.w(TAG, "Tried to send a null key event. Ignoring."); 1713c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik return; 1723c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik } 1738a2cfc309ab9126e90022916967c65a793c034f0RoboErik mSessionManager.dispatchMediaKeyEvent(keyEvent, needWakeLock); 1748a2cfc309ab9126e90022916967c65a793c034f0RoboErik if (DEBUG) { 1758a2cfc309ab9126e90022916967c65a793c034f0RoboErik Log.d(TAG, "dispatched media key " + keyEvent); 1768a2cfc309ab9126e90022916967c65a793c034f0RoboErik } 1778a2cfc309ab9126e90022916967c65a793c034f0RoboErik } 178f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 1795026936e49540449165fd5881231f8970a29ea91Jaewan Kim public void sendVolumeKeyEvent(KeyEvent keyEvent, int stream, boolean musicOnly) { 1803c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik if (keyEvent == null) { 1813c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik Log.w(TAG, "Tried to send a null key event. Ignoring."); 1823c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik return; 1833c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik } 1845026936e49540449165fd5881231f8970a29ea91Jaewan Kim mSessionManager.dispatchVolumeKeyEvent(keyEvent, stream, musicOnly); 1853c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik } 1863c45c29109d23981d8b707c809b3b43ce2e20fc3RoboErik 187b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik public void sendAdjustVolumeBy(int suggestedStream, int delta, int flags) { 1881ff5b1648a051e9650614f0c0f1b3f449777db81RoboErik mSessionManager.dispatchAdjustVolume(suggestedStream, delta, flags); 189b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik if (DEBUG) { 190b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik Log.d(TAG, "dispatched volume adjustment"); 191b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik } 192b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik } 193b69ffd4dc2c8fa85e0064151141ebeee90de471eRoboErik 194de9ba39c1714f5bc9e1785d8224ad26c132b6293RoboErik public boolean isGlobalPriorityActive() { 195de9ba39c1714f5bc9e1785d8224ad26c132b6293RoboErik return mSessionManager.isGlobalPriorityActive(); 196de9ba39c1714f5bc9e1785d8224ad26c132b6293RoboErik } 197de9ba39c1714f5bc9e1785d8224ad26c132b6293RoboErik 198477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public void addRccListener(PendingIntent pi, MediaSession.Callback listener) { 1998a2cfc309ab9126e90022916967c65a793c034f0RoboErik if (pi == null) { 2008a2cfc309ab9126e90022916967c65a793c034f0RoboErik Log.w(TAG, "Pending intent was null, can't add rcc listener."); 2018a2cfc309ab9126e90022916967c65a793c034f0RoboErik return; 2028a2cfc309ab9126e90022916967c65a793c034f0RoboErik } 203f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik SessionHolder holder = getHolder(pi, true); 2048b4bffcac996b4083e720310a09d315ca1c4a000RoboErik if (holder == null) { 2058b4bffcac996b4083e720310a09d315ca1c4a000RoboErik return; 2068b4bffcac996b4083e720310a09d315ca1c4a000RoboErik } 207f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (holder.mRccListener != null) { 208f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (holder.mRccListener == listener) { 2098a2cfc309ab9126e90022916967c65a793c034f0RoboErik if (DEBUG) { 2108a2cfc309ab9126e90022916967c65a793c034f0RoboErik Log.d(TAG, "addRccListener listener already added."); 2118a2cfc309ab9126e90022916967c65a793c034f0RoboErik } 212f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik // This is already the registered listener, ignore 213f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik return; 214f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 215f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 216f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik holder.mRccListener = listener; 21742ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik holder.mFlags |= MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS; 218a8f951462791a16f47e8c07e552232f31dcefac5RoboErik holder.mSession.setFlags(holder.mFlags); 219f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik holder.update(); 2208a2cfc309ab9126e90022916967c65a793c034f0RoboErik if (DEBUG) { 2218a2cfc309ab9126e90022916967c65a793c034f0RoboErik Log.d(TAG, "Added rcc listener for " + pi + "."); 2228a2cfc309ab9126e90022916967c65a793c034f0RoboErik } 223f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 224f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 225f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik public void removeRccListener(PendingIntent pi) { 2268a2cfc309ab9126e90022916967c65a793c034f0RoboErik if (pi == null) { 2278a2cfc309ab9126e90022916967c65a793c034f0RoboErik return; 2288a2cfc309ab9126e90022916967c65a793c034f0RoboErik } 229f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik SessionHolder holder = getHolder(pi, false); 230f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (holder != null && holder.mRccListener != null) { 231f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik holder.mRccListener = null; 23242ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik holder.mFlags &= ~MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS; 233a8f951462791a16f47e8c07e552232f31dcefac5RoboErik holder.mSession.setFlags(holder.mFlags); 234f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik holder.update(); 2358a2cfc309ab9126e90022916967c65a793c034f0RoboErik if (DEBUG) { 2368a2cfc309ab9126e90022916967c65a793c034f0RoboErik Log.d(TAG, "Removed rcc listener for " + pi + "."); 2378a2cfc309ab9126e90022916967c65a793c034f0RoboErik } 238f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 239f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 240f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 2416f0e4ddd66fcdcc13944d8970d0b560e2626508bRoboErik public void addMediaButtonListener(PendingIntent pi, ComponentName mbrComponent, 242f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik Context context) { 2438a2cfc309ab9126e90022916967c65a793c034f0RoboErik if (pi == null) { 2448a2cfc309ab9126e90022916967c65a793c034f0RoboErik Log.w(TAG, "Pending intent was null, can't addMediaButtonListener."); 2458a2cfc309ab9126e90022916967c65a793c034f0RoboErik return; 2468a2cfc309ab9126e90022916967c65a793c034f0RoboErik } 247f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik SessionHolder holder = getHolder(pi, true); 2488b4bffcac996b4083e720310a09d315ca1c4a000RoboErik if (holder == null) { 2498b4bffcac996b4083e720310a09d315ca1c4a000RoboErik return; 2508b4bffcac996b4083e720310a09d315ca1c4a000RoboErik } 251f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (holder.mMediaButtonListener != null) { 252477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik // Already have this listener registered 2538a2cfc309ab9126e90022916967c65a793c034f0RoboErik if (DEBUG) { 2548a2cfc309ab9126e90022916967c65a793c034f0RoboErik Log.d(TAG, "addMediaButtonListener already added " + pi); 2558a2cfc309ab9126e90022916967c65a793c034f0RoboErik } 256f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 257f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik holder.mMediaButtonListener = new MediaButtonListener(pi, context); 258418c10ca9df1505509afeffd558cd92fc97bc635RoboErik // TODO determine if handling transport performer commands should also 259418c10ca9df1505509afeffd558cd92fc97bc635RoboErik // set this flag 26042ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik holder.mFlags |= MediaSession.FLAG_HANDLES_MEDIA_BUTTONS; 261a8f951462791a16f47e8c07e552232f31dcefac5RoboErik holder.mSession.setFlags(holder.mFlags); 262b214efbb9170a9f6a4991684a63ca59680074cc7RoboErik holder.mSession.setMediaButtonReceiver(pi); 263477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik holder.update(); 2648a2cfc309ab9126e90022916967c65a793c034f0RoboErik if (DEBUG) { 2658a2cfc309ab9126e90022916967c65a793c034f0RoboErik Log.d(TAG, "addMediaButtonListener added " + pi); 2668a2cfc309ab9126e90022916967c65a793c034f0RoboErik } 267f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 268f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 269f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik public void removeMediaButtonListener(PendingIntent pi) { 2708a2cfc309ab9126e90022916967c65a793c034f0RoboErik if (pi == null) { 2718a2cfc309ab9126e90022916967c65a793c034f0RoboErik return; 2728a2cfc309ab9126e90022916967c65a793c034f0RoboErik } 273f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik SessionHolder holder = getHolder(pi, false); 274f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (holder != null && holder.mMediaButtonListener != null) { 27542ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik holder.mFlags &= ~MediaSession.FLAG_HANDLES_MEDIA_BUTTONS; 276a8f951462791a16f47e8c07e552232f31dcefac5RoboErik holder.mSession.setFlags(holder.mFlags); 277a8f951462791a16f47e8c07e552232f31dcefac5RoboErik holder.mMediaButtonListener = null; 2788a2cfc309ab9126e90022916967c65a793c034f0RoboErik 279f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik holder.update(); 2808a2cfc309ab9126e90022916967c65a793c034f0RoboErik if (DEBUG) { 2818a2cfc309ab9126e90022916967c65a793c034f0RoboErik Log.d(TAG, "removeMediaButtonListener removed " + pi); 2828a2cfc309ab9126e90022916967c65a793c034f0RoboErik } 283f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 284f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 285f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 286a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik /** 287a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik * Scale a bitmap to fit the smallest dimension by uniformly scaling the 288a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik * incoming bitmap. If the bitmap fits, then do nothing and return the 289a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik * original. 290a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik * 291a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik * @param bitmap 292a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik * @param maxWidth 293a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik * @param maxHeight 294a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik * @return 295a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik */ 296a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik private static Bitmap scaleBitmapIfTooBig(Bitmap bitmap, int maxWidth, int maxHeight) { 297a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik if (bitmap != null) { 298a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik final int width = bitmap.getWidth(); 299a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik final int height = bitmap.getHeight(); 300a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik if (width > maxWidth || height > maxHeight) { 301a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik float scale = Math.min((float) maxWidth / width, (float) maxHeight / height); 302a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik int newWidth = Math.round(scale * width); 303a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik int newHeight = Math.round(scale * height); 304a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik Bitmap.Config newConfig = bitmap.getConfig(); 305a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik if (newConfig == null) { 306a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik newConfig = Bitmap.Config.ARGB_8888; 307a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik } 308a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik Bitmap outBitmap = Bitmap.createBitmap(newWidth, newHeight, newConfig); 309a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik Canvas canvas = new Canvas(outBitmap); 310a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik Paint paint = new Paint(); 311a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik paint.setAntiAlias(true); 312a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik paint.setFilterBitmap(true); 313a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik canvas.drawBitmap(bitmap, null, 314a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik new RectF(0, 0, outBitmap.getWidth(), outBitmap.getHeight()), paint); 315a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik bitmap = outBitmap; 316a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik } 317a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik } 318a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik return bitmap; 319a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik } 320a259d35073ada384a5810f2a0f4f92f5fd27d85fRoboErik 321f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik private SessionHolder getHolder(PendingIntent pi, boolean createIfMissing) { 322f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik SessionHolder holder = mSessions.get(pi); 323f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (holder == null && createIfMissing) { 3248b4bffcac996b4083e720310a09d315ca1c4a000RoboErik MediaSession session; 325aa4e23bbb36994708ba72c5f4c83255025d99e07RoboErik session = new MediaSession(mContext, TAG + "-" + pi.getCreatorPackage()); 326a8f951462791a16f47e8c07e552232f31dcefac5RoboErik session.setActive(true); 327f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik holder = new SessionHolder(session, pi); 328f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik mSessions.put(pi, holder); 329f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 330f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik return holder; 331f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 332f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 3338a2cfc309ab9126e90022916967c65a793c034f0RoboErik private static void sendKeyEvent(PendingIntent pi, Context context, Intent intent) { 3348a2cfc309ab9126e90022916967c65a793c034f0RoboErik try { 3358a2cfc309ab9126e90022916967c65a793c034f0RoboErik pi.send(context, 0, intent); 3368a2cfc309ab9126e90022916967c65a793c034f0RoboErik } catch (CanceledException e) { 3378a2cfc309ab9126e90022916967c65a793c034f0RoboErik Log.e(TAG, "Error sending media key down event:", e); 3388a2cfc309ab9126e90022916967c65a793c034f0RoboErik // Don't bother sending up if down failed 3398a2cfc309ab9126e90022916967c65a793c034f0RoboErik return; 3408a2cfc309ab9126e90022916967c65a793c034f0RoboErik } 3418a2cfc309ab9126e90022916967c65a793c034f0RoboErik } 3428a2cfc309ab9126e90022916967c65a793c034f0RoboErik 343477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik private static final class MediaButtonListener extends MediaSession.Callback { 3448a2cfc309ab9126e90022916967c65a793c034f0RoboErik private final PendingIntent mPendingIntent; 3458a2cfc309ab9126e90022916967c65a793c034f0RoboErik private final Context mContext; 3468a2cfc309ab9126e90022916967c65a793c034f0RoboErik 347477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public MediaButtonListener(PendingIntent pi, Context context) { 3488a2cfc309ab9126e90022916967c65a793c034f0RoboErik mPendingIntent = pi; 3498a2cfc309ab9126e90022916967c65a793c034f0RoboErik mContext = context; 3508a2cfc309ab9126e90022916967c65a793c034f0RoboErik } 3518a2cfc309ab9126e90022916967c65a793c034f0RoboErik 3528a2cfc309ab9126e90022916967c65a793c034f0RoboErik @Override 353477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public boolean onMediaButtonEvent(Intent mediaButtonIntent) { 3548a2cfc309ab9126e90022916967c65a793c034f0RoboErik MediaSessionLegacyHelper.sendKeyEvent(mPendingIntent, mContext, mediaButtonIntent); 355477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik return true; 356f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 357f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 358f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik @Override 359f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik public void onPlay() { 360f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik sendKeyEvent(KeyEvent.KEYCODE_MEDIA_PLAY); 361f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 362f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 363f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik @Override 364f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik public void onPause() { 365f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik sendKeyEvent(KeyEvent.KEYCODE_MEDIA_PAUSE); 366f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 367f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 368f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik @Override 36979fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik public void onSkipToNext() { 370f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik sendKeyEvent(KeyEvent.KEYCODE_MEDIA_NEXT); 371f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 372f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 373f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik @Override 37479fa4630bbca7c6c251eea99fe8997e4b45beceeRoboErik public void onSkipToPrevious() { 375f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik sendKeyEvent(KeyEvent.KEYCODE_MEDIA_PREVIOUS); 376f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 377f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 378f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik @Override 379f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik public void onFastForward() { 380f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik sendKeyEvent(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD); 381f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 382f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 383f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik @Override 384f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik public void onRewind() { 385f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik sendKeyEvent(KeyEvent.KEYCODE_MEDIA_REWIND); 386f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 387f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 388f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik @Override 389f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik public void onStop() { 390f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik sendKeyEvent(KeyEvent.KEYCODE_MEDIA_STOP); 391f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 392f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 393f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik private void sendKeyEvent(int keyCode) { 394f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik KeyEvent ke = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode); 395f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON); 3966c09004ec09951712ab57473810fa6b85f5783cdJean-Michel Trivi intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); 397f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 398f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik intent.putExtra(Intent.EXTRA_KEY_EVENT, ke); 3998a2cfc309ab9126e90022916967c65a793c034f0RoboErik MediaSessionLegacyHelper.sendKeyEvent(mPendingIntent, mContext, intent); 400f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 401f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik ke = new KeyEvent(KeyEvent.ACTION_UP, keyCode); 402f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik intent.putExtra(Intent.EXTRA_KEY_EVENT, ke); 4038a2cfc309ab9126e90022916967c65a793c034f0RoboErik MediaSessionLegacyHelper.sendKeyEvent(mPendingIntent, mContext, intent); 4048a2cfc309ab9126e90022916967c65a793c034f0RoboErik 4058a2cfc309ab9126e90022916967c65a793c034f0RoboErik if (DEBUG) { 4068a2cfc309ab9126e90022916967c65a793c034f0RoboErik Log.d(TAG, "Sent " + keyCode + " to pending intent " + mPendingIntent); 407f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 408f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 409f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 410f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 411f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik private class SessionHolder { 41242ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik public final MediaSession mSession; 413f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik public final PendingIntent mPi; 414f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik public MediaButtonListener mMediaButtonListener; 415477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public MediaSession.Callback mRccListener; 416a8f951462791a16f47e8c07e552232f31dcefac5RoboErik public int mFlags; 417f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 418477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public SessionCallback mCb; 419477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik 42042ea7eecd149161ed192d3029f0d77d1d08a4aa5RoboErik public SessionHolder(MediaSession session, PendingIntent pi) { 421f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik mSession = session; 422f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik mPi = pi; 423f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 424f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik 425f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik public void update() { 426f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik if (mMediaButtonListener == null && mRccListener == null) { 427477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik mSession.setCallback(null); 428f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik mSession.release(); 429477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik mCb = null; 430f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik mSessions.remove(mPi); 431477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } else if (mCb == null) { 432477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik mCb = new SessionCallback(); 4339ff7dda93e59e1e0032f5b96633d1479ab307a11RoboErik Handler handler = new Handler(Looper.getMainLooper()); 43478c64cdbd82a4d8feb7faf43109b86ab87252dd1RoboErik mSession.setCallback(mCb, handler); 435477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 436477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 437477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik 438477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik private class SessionCallback extends MediaSession.Callback { 439477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik 440477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik @Override 441477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public boolean onMediaButtonEvent(Intent mediaButtonIntent) { 442477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if (mMediaButtonListener != null) { 443477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik mMediaButtonListener.onMediaButtonEvent(mediaButtonIntent); 444477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 445477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik return true; 446477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 447477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik 448477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik @Override 449477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public void onPlay() { 450477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if (mMediaButtonListener != null) { 451477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik mMediaButtonListener.onPlay(); 452477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 453477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 454477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik 455477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik @Override 456477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public void onPause() { 457477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if (mMediaButtonListener != null) { 458477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik mMediaButtonListener.onPause(); 459477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 460477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 461477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik 462477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik @Override 463477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public void onSkipToNext() { 464477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if (mMediaButtonListener != null) { 465477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik mMediaButtonListener.onSkipToNext(); 466477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 467477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 468477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik 469477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik @Override 470477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public void onSkipToPrevious() { 471477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if (mMediaButtonListener != null) { 472477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik mMediaButtonListener.onSkipToPrevious(); 473477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 474477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 475477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik 476477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik @Override 477477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public void onFastForward() { 478477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if (mMediaButtonListener != null) { 479477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik mMediaButtonListener.onFastForward(); 480477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 481477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 482477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik 483477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik @Override 484477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public void onRewind() { 485477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if (mMediaButtonListener != null) { 486477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik mMediaButtonListener.onRewind(); 487477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 488477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 489477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik 490477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik @Override 491477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public void onStop() { 492477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if (mMediaButtonListener != null) { 493477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik mMediaButtonListener.onStop(); 494477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 495477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 496477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik 497477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik @Override 498477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public void onSeekTo(long pos) { 499477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if (mRccListener != null) { 500477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik mRccListener.onSeekTo(pos); 501477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 502477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 503477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik 504477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik @Override 505477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik public void onSetRating(Rating rating) { 506477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik if (mRccListener != null) { 507477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik mRccListener.onSetRating(rating); 508477d1197c3c25c01ace7ea4494437c23720a2eb3RoboErik } 509f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 510f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 511f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik } 512f1372428f2df781c71c71caa2f6a4db6f847cf10RoboErik} 513