1 /* 2 * Copyright (C) 2016 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 androidx.leanback.media; 18 19 import android.content.Context; 20 import android.graphics.Bitmap; 21 import android.graphics.drawable.BitmapDrawable; 22 import android.graphics.drawable.Drawable; 23 import android.os.Bundle; 24 import android.support.v4.media.MediaMetadataCompat; 25 import android.support.v4.media.session.MediaControllerCompat; 26 import android.support.v4.media.session.PlaybackStateCompat; 27 import android.util.Log; 28 29 /** 30 * A helper class for implementing a glue layer for {@link MediaControllerCompat}. 31 * @deprecated Use {@link MediaControllerAdapter} with {@link PlaybackTransportControlGlue} or 32 * {@link PlaybackBannerControlGlue}. 33 */ 34 @Deprecated 35 public abstract class MediaControllerGlue extends PlaybackControlGlue { 36 static final String TAG = "MediaControllerGlue"; 37 static final boolean DEBUG = false; 38 39 MediaControllerCompat mMediaController; 40 41 private final MediaControllerCompat.Callback mCallback = new MediaControllerCompat.Callback() { 42 @Override 43 public void onMetadataChanged(MediaMetadataCompat metadata) { 44 if (DEBUG) Log.v(TAG, "onMetadataChanged"); 45 MediaControllerGlue.this.onMetadataChanged(); 46 } 47 @Override 48 public void onPlaybackStateChanged(PlaybackStateCompat state) { 49 if (DEBUG) Log.v(TAG, "onPlaybackStateChanged"); 50 onStateChanged(); 51 } 52 @Override 53 public void onSessionDestroyed() { 54 if (DEBUG) Log.v(TAG, "onSessionDestroyed"); 55 mMediaController = null; 56 } 57 @Override 58 public void onSessionEvent(String event, Bundle extras) { 59 if (DEBUG) Log.v(TAG, "onSessionEvent"); 60 } 61 }; 62 63 /** 64 * Constructor for the glue. 65 * 66 * @param context 67 * @param fastForwardSpeeds Array of seek speeds for fast forward. 68 * @param rewindSpeeds Array of seek speeds for rewind. 69 */ 70 public MediaControllerGlue(Context context, 71 int[] fastForwardSpeeds, 72 int[] rewindSpeeds) { 73 super(context, fastForwardSpeeds, rewindSpeeds); 74 } 75 76 /** 77 * Attaches to the given media controller. 78 */ 79 public void attachToMediaController(MediaControllerCompat mediaController) { 80 if (mediaController != mMediaController) { 81 if (DEBUG) Log.v(TAG, "New media controller " + mediaController); 82 detach(); 83 mMediaController = mediaController; 84 if (mMediaController != null) { 85 mMediaController.registerCallback(mCallback); 86 } 87 onMetadataChanged(); 88 onStateChanged(); 89 } 90 } 91 92 /** 93 * Detaches from the media controller. Must be called when the object is no longer 94 * needed. 95 */ 96 public void detach() { 97 if (mMediaController != null) { 98 mMediaController.unregisterCallback(mCallback); 99 } 100 mMediaController = null; 101 } 102 103 /** 104 * Returns the media controller currently attached. 105 */ 106 public final MediaControllerCompat getMediaController() { 107 return mMediaController; 108 } 109 110 @Override 111 public boolean hasValidMedia() { 112 return mMediaController != null && mMediaController.getMetadata() != null; 113 } 114 115 @Override 116 public boolean isMediaPlaying() { 117 return mMediaController.getPlaybackState().getState() == PlaybackStateCompat.STATE_PLAYING; 118 } 119 120 @Override 121 public int getCurrentSpeedId() { 122 int speed = (int) mMediaController.getPlaybackState().getPlaybackSpeed(); 123 if (speed == 0) { 124 return PLAYBACK_SPEED_PAUSED; 125 } else if (speed == 1) { 126 return PLAYBACK_SPEED_NORMAL; 127 } else if (speed > 0) { 128 int[] seekSpeeds = getFastForwardSpeeds(); 129 for (int index = 0; index < seekSpeeds.length; index++) { 130 if (speed == seekSpeeds[index]) { 131 return PLAYBACK_SPEED_FAST_L0 + index; 132 } 133 } 134 } else { 135 int[] seekSpeeds = getRewindSpeeds(); 136 for (int index = 0; index < seekSpeeds.length; index++) { 137 if (-speed == seekSpeeds[index]) { 138 return -PLAYBACK_SPEED_FAST_L0 - index; 139 } 140 } 141 } 142 Log.w(TAG, "Couldn't find index for speed " + speed); 143 return PLAYBACK_SPEED_INVALID; 144 } 145 146 @Override 147 public CharSequence getMediaTitle() { 148 return mMediaController.getMetadata().getDescription().getTitle(); 149 } 150 151 @Override 152 public CharSequence getMediaSubtitle() { 153 return mMediaController.getMetadata().getDescription().getSubtitle(); 154 } 155 156 @Override 157 public int getMediaDuration() { 158 return (int) mMediaController.getMetadata().getLong( 159 MediaMetadataCompat.METADATA_KEY_DURATION); 160 } 161 162 @Override 163 public int getCurrentPosition() { 164 return (int) mMediaController.getPlaybackState().getPosition(); 165 } 166 167 @Override 168 public Drawable getMediaArt() { 169 Bitmap bitmap = mMediaController.getMetadata().getDescription().getIconBitmap(); 170 return bitmap == null ? null : new BitmapDrawable(getContext().getResources(), bitmap); 171 } 172 173 @Override 174 public long getSupportedActions() { 175 long result = 0; 176 long actions = mMediaController.getPlaybackState().getActions(); 177 if ((actions & PlaybackStateCompat.ACTION_PLAY_PAUSE) != 0) { 178 result |= ACTION_PLAY_PAUSE; 179 } 180 if ((actions & PlaybackStateCompat.ACTION_SKIP_TO_NEXT) != 0) { 181 result |= ACTION_SKIP_TO_NEXT; 182 } 183 if ((actions & PlaybackStateCompat.ACTION_SKIP_TO_PREVIOUS) != 0) { 184 result |= ACTION_SKIP_TO_PREVIOUS; 185 } 186 if ((actions & PlaybackStateCompat.ACTION_FAST_FORWARD) != 0) { 187 result |= ACTION_FAST_FORWARD; 188 } 189 if ((actions & PlaybackStateCompat.ACTION_REWIND) != 0) { 190 result |= ACTION_REWIND; 191 } 192 return result; 193 } 194 195 @Override 196 public void play(int speed) { 197 if (DEBUG) Log.v(TAG, "startPlayback speed " + speed); 198 if (speed == PLAYBACK_SPEED_NORMAL) { 199 mMediaController.getTransportControls().play(); 200 } else if (speed > 0) { 201 mMediaController.getTransportControls().fastForward(); 202 } else { 203 mMediaController.getTransportControls().rewind(); 204 } 205 } 206 207 @Override 208 public void pause() { 209 if (DEBUG) Log.v(TAG, "pausePlayback"); 210 mMediaController.getTransportControls().pause(); 211 } 212 213 @Override 214 public void next() { 215 if (DEBUG) Log.v(TAG, "skipToNext"); 216 mMediaController.getTransportControls().skipToNext(); 217 } 218 219 @Override 220 public void previous() { 221 if (DEBUG) Log.v(TAG, "skipToPrevious"); 222 mMediaController.getTransportControls().skipToPrevious(); 223 } 224 } 225