517 lines
20 KiB
Java
517 lines
20 KiB
Java
![]() |
/*
|
||
|
* Copyright (C) 2014 The Android Open Source Project
|
||
|
*
|
||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||
|
* you may not use this file except in compliance with the License.
|
||
|
* You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing, software
|
||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||
|
* See the License for the specific language governing permissions and
|
||
|
* limitations under the License.
|
||
|
*/
|
||
|
|
||
|
package android.media.session;
|
||
|
|
||
|
import android.app.PendingIntent;
|
||
|
import android.app.PendingIntent.CanceledException;
|
||
|
import android.compat.annotation.UnsupportedAppUsage;
|
||
|
import android.content.ComponentName;
|
||
|
import android.content.Context;
|
||
|
import android.content.Intent;
|
||
|
import android.graphics.Bitmap;
|
||
|
import android.graphics.Canvas;
|
||
|
import android.graphics.Paint;
|
||
|
import android.graphics.RectF;
|
||
|
import android.media.MediaCommunicationManager;
|
||
|
import android.media.MediaMetadata;
|
||
|
import android.media.MediaMetadataEditor;
|
||
|
import android.media.MediaMetadataRetriever;
|
||
|
import android.media.Rating;
|
||
|
import android.os.Bundle;
|
||
|
import android.os.Handler;
|
||
|
import android.os.Looper;
|
||
|
import android.util.ArrayMap;
|
||
|
import android.util.Log;
|
||
|
import android.view.KeyEvent;
|
||
|
|
||
|
/**
|
||
|
* Helper for connecting existing APIs up to the new session APIs. This can be
|
||
|
* used by RCC, AudioFocus, etc. to create a single session that translates to
|
||
|
* all those components.
|
||
|
*
|
||
|
* @hide
|
||
|
*/
|
||
|
public class MediaSessionLegacyHelper {
|
||
|
private static final String TAG = "MediaSessionHelper";
|
||
|
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
|
||
|
|
||
|
private static final Object sLock = new Object();
|
||
|
private static MediaSessionLegacyHelper sInstance;
|
||
|
|
||
|
private Context mContext;
|
||
|
private MediaSessionManager mSessionManager;
|
||
|
private MediaCommunicationManager mCommunicationManager;
|
||
|
private Handler mHandler = new Handler(Looper.getMainLooper());
|
||
|
// The legacy APIs use PendingIntents to register/unregister media button
|
||
|
// receivers and these are associated with RCC.
|
||
|
private ArrayMap<PendingIntent, SessionHolder> mSessions
|
||
|
= new ArrayMap<PendingIntent, SessionHolder>();
|
||
|
|
||
|
private MediaSessionLegacyHelper(Context context) {
|
||
|
mContext = context;
|
||
|
mSessionManager = (MediaSessionManager) context
|
||
|
.getSystemService(Context.MEDIA_SESSION_SERVICE);
|
||
|
mCommunicationManager = context.getSystemService(MediaCommunicationManager.class);
|
||
|
}
|
||
|
|
||
|
@UnsupportedAppUsage
|
||
|
public static MediaSessionLegacyHelper getHelper(Context context) {
|
||
|
synchronized (sLock) {
|
||
|
if (sInstance == null) {
|
||
|
sInstance = new MediaSessionLegacyHelper(context.getApplicationContext());
|
||
|
}
|
||
|
}
|
||
|
return sInstance;
|
||
|
}
|
||
|
|
||
|
public static Bundle getOldMetadata(MediaMetadata metadata, int artworkWidth,
|
||
|
int artworkHeight) {
|
||
|
boolean includeArtwork = artworkWidth != -1 && artworkHeight != -1;
|
||
|
Bundle oldMetadata = new Bundle();
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM)) {
|
||
|
oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ALBUM),
|
||
|
metadata.getString(MediaMetadata.METADATA_KEY_ALBUM));
|
||
|
}
|
||
|
if (includeArtwork && metadata.containsKey(MediaMetadata.METADATA_KEY_ART)) {
|
||
|
Bitmap art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ART);
|
||
|
oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK),
|
||
|
scaleBitmapIfTooBig(art, artworkWidth, artworkHeight));
|
||
|
} else if (includeArtwork && metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ART)) {
|
||
|
// Fall back to album art if the track art wasn't available
|
||
|
Bitmap art = metadata.getBitmap(MediaMetadata.METADATA_KEY_ALBUM_ART);
|
||
|
oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.BITMAP_KEY_ARTWORK),
|
||
|
scaleBitmapIfTooBig(art, artworkWidth, artworkHeight));
|
||
|
}
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_ALBUM_ARTIST)) {
|
||
|
oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ALBUMARTIST),
|
||
|
metadata.getString(MediaMetadata.METADATA_KEY_ALBUM_ARTIST));
|
||
|
}
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_ARTIST)) {
|
||
|
oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_ARTIST),
|
||
|
metadata.getString(MediaMetadata.METADATA_KEY_ARTIST));
|
||
|
}
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_AUTHOR)) {
|
||
|
oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_AUTHOR),
|
||
|
metadata.getString(MediaMetadata.METADATA_KEY_AUTHOR));
|
||
|
}
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_COMPILATION)) {
|
||
|
oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_COMPILATION),
|
||
|
metadata.getString(MediaMetadata.METADATA_KEY_COMPILATION));
|
||
|
}
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_COMPOSER)) {
|
||
|
oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_COMPOSER),
|
||
|
metadata.getString(MediaMetadata.METADATA_KEY_COMPOSER));
|
||
|
}
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_DATE)) {
|
||
|
oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DATE),
|
||
|
metadata.getString(MediaMetadata.METADATA_KEY_DATE));
|
||
|
}
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_DISC_NUMBER)) {
|
||
|
oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DISC_NUMBER),
|
||
|
metadata.getLong(MediaMetadata.METADATA_KEY_DISC_NUMBER));
|
||
|
}
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) {
|
||
|
oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_DURATION),
|
||
|
metadata.getLong(MediaMetadata.METADATA_KEY_DURATION));
|
||
|
}
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_GENRE)) {
|
||
|
oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_GENRE),
|
||
|
metadata.getString(MediaMetadata.METADATA_KEY_GENRE));
|
||
|
}
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_NUM_TRACKS)) {
|
||
|
oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_NUM_TRACKS),
|
||
|
metadata.getLong(MediaMetadata.METADATA_KEY_NUM_TRACKS));
|
||
|
}
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_RATING)) {
|
||
|
oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.RATING_KEY_BY_OTHERS),
|
||
|
metadata.getRating(MediaMetadata.METADATA_KEY_RATING));
|
||
|
}
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_USER_RATING)) {
|
||
|
oldMetadata.putParcelable(String.valueOf(MediaMetadataEditor.RATING_KEY_BY_USER),
|
||
|
metadata.getRating(MediaMetadata.METADATA_KEY_USER_RATING));
|
||
|
}
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_TITLE)) {
|
||
|
oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_TITLE),
|
||
|
metadata.getString(MediaMetadata.METADATA_KEY_TITLE));
|
||
|
}
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_TRACK_NUMBER)) {
|
||
|
oldMetadata.putLong(
|
||
|
String.valueOf(MediaMetadataRetriever.METADATA_KEY_CD_TRACK_NUMBER),
|
||
|
metadata.getLong(MediaMetadata.METADATA_KEY_TRACK_NUMBER));
|
||
|
}
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_WRITER)) {
|
||
|
oldMetadata.putString(String.valueOf(MediaMetadataRetriever.METADATA_KEY_WRITER),
|
||
|
metadata.getString(MediaMetadata.METADATA_KEY_WRITER));
|
||
|
}
|
||
|
if (metadata.containsKey(MediaMetadata.METADATA_KEY_YEAR)) {
|
||
|
oldMetadata.putLong(String.valueOf(MediaMetadataRetriever.METADATA_KEY_YEAR),
|
||
|
metadata.getLong(MediaMetadata.METADATA_KEY_YEAR));
|
||
|
}
|
||
|
return oldMetadata;
|
||
|
}
|
||
|
|
||
|
public MediaSession getSession(PendingIntent pi) {
|
||
|
SessionHolder holder = mSessions.get(pi);
|
||
|
return holder == null ? null : holder.mSession;
|
||
|
}
|
||
|
|
||
|
public void sendMediaButtonEvent(KeyEvent keyEvent, boolean needWakeLock) {
|
||
|
if (keyEvent == null) {
|
||
|
Log.w(TAG, "Tried to send a null key event. Ignoring.");
|
||
|
return;
|
||
|
}
|
||
|
mCommunicationManager.dispatchMediaKeyEvent(keyEvent, needWakeLock);
|
||
|
if (DEBUG) {
|
||
|
Log.d(TAG, "dispatched media key " + keyEvent);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void sendVolumeKeyEvent(KeyEvent keyEvent, int stream, boolean musicOnly) {
|
||
|
if (keyEvent == null) {
|
||
|
Log.w(TAG, "Tried to send a null key event. Ignoring.");
|
||
|
return;
|
||
|
}
|
||
|
mSessionManager.dispatchVolumeKeyEvent(keyEvent, stream, musicOnly);
|
||
|
}
|
||
|
|
||
|
public void sendAdjustVolumeBy(int suggestedStream, int delta, int flags) {
|
||
|
mSessionManager.dispatchAdjustVolume(suggestedStream, delta, flags);
|
||
|
if (DEBUG) {
|
||
|
Log.d(TAG, "dispatched volume adjustment");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public boolean isGlobalPriorityActive() {
|
||
|
return mSessionManager.isGlobalPriorityActive();
|
||
|
}
|
||
|
|
||
|
public void addRccListener(PendingIntent pi, MediaSession.Callback listener) {
|
||
|
if (pi == null) {
|
||
|
Log.w(TAG, "Pending intent was null, can't add rcc listener.");
|
||
|
return;
|
||
|
}
|
||
|
SessionHolder holder = getHolder(pi, true);
|
||
|
if (holder == null) {
|
||
|
return;
|
||
|
}
|
||
|
if (holder.mRccListener != null) {
|
||
|
if (holder.mRccListener == listener) {
|
||
|
if (DEBUG) {
|
||
|
Log.d(TAG, "addRccListener listener already added.");
|
||
|
}
|
||
|
// This is already the registered listener, ignore
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
holder.mRccListener = listener;
|
||
|
holder.mFlags |= MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS;
|
||
|
holder.mSession.setFlags(holder.mFlags);
|
||
|
holder.update();
|
||
|
if (DEBUG) {
|
||
|
Log.d(TAG, "Added rcc listener for " + pi + ".");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void removeRccListener(PendingIntent pi) {
|
||
|
if (pi == null) {
|
||
|
return;
|
||
|
}
|
||
|
SessionHolder holder = getHolder(pi, false);
|
||
|
if (holder != null && holder.mRccListener != null) {
|
||
|
holder.mRccListener = null;
|
||
|
holder.mFlags &= ~MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS;
|
||
|
holder.mSession.setFlags(holder.mFlags);
|
||
|
holder.update();
|
||
|
if (DEBUG) {
|
||
|
Log.d(TAG, "Removed rcc listener for " + pi + ".");
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void addMediaButtonListener(PendingIntent pi, ComponentName mbrComponent,
|
||
|
Context context) {
|
||
|
if (pi == null) {
|
||
|
Log.w(TAG, "Pending intent was null, can't addMediaButtonListener.");
|
||
|
return;
|
||
|
}
|
||
|
SessionHolder holder = getHolder(pi, true);
|
||
|
if (holder == null) {
|
||
|
return;
|
||
|
}
|
||
|
if (holder.mMediaButtonListener != null) {
|
||
|
// Already have this listener registered
|
||
|
if (DEBUG) {
|
||
|
Log.d(TAG, "addMediaButtonListener already added " + pi);
|
||
|
}
|
||
|
}
|
||
|
holder.mMediaButtonListener = new MediaButtonListener(pi, context);
|
||
|
// TODO determine if handling transport performer commands should also
|
||
|
// set this flag
|
||
|
holder.mFlags |= MediaSession.FLAG_HANDLES_MEDIA_BUTTONS;
|
||
|
holder.mSession.setFlags(holder.mFlags);
|
||
|
holder.mSession.setMediaButtonReceiver(pi);
|
||
|
holder.update();
|
||
|
if (DEBUG) {
|
||
|
Log.d(TAG, "addMediaButtonListener added " + pi);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public void removeMediaButtonListener(PendingIntent pi) {
|
||
|
if (pi == null) {
|
||
|
return;
|
||
|
}
|
||
|
SessionHolder holder = getHolder(pi, false);
|
||
|
if (holder != null && holder.mMediaButtonListener != null) {
|
||
|
holder.mFlags &= ~MediaSession.FLAG_HANDLES_MEDIA_BUTTONS;
|
||
|
holder.mSession.setFlags(holder.mFlags);
|
||
|
holder.mMediaButtonListener = null;
|
||
|
|
||
|
holder.update();
|
||
|
if (DEBUG) {
|
||
|
Log.d(TAG, "removeMediaButtonListener removed " + pi);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Scale a bitmap to fit the smallest dimension by uniformly scaling the
|
||
|
* incoming bitmap. If the bitmap fits, then do nothing and return the
|
||
|
* original.
|
||
|
*
|
||
|
* @param bitmap
|
||
|
* @param maxWidth
|
||
|
* @param maxHeight
|
||
|
* @return
|
||
|
*/
|
||
|
private static Bitmap scaleBitmapIfTooBig(Bitmap bitmap, int maxWidth, int maxHeight) {
|
||
|
if (bitmap != null) {
|
||
|
final int width = bitmap.getWidth();
|
||
|
final int height = bitmap.getHeight();
|
||
|
if (width > maxWidth || height > maxHeight) {
|
||
|
float scale = Math.min((float) maxWidth / width, (float) maxHeight / height);
|
||
|
int newWidth = Math.round(scale * width);
|
||
|
int newHeight = Math.round(scale * height);
|
||
|
Bitmap.Config newConfig = bitmap.getConfig();
|
||
|
if (newConfig == null) {
|
||
|
newConfig = Bitmap.Config.ARGB_8888;
|
||
|
}
|
||
|
Bitmap outBitmap = Bitmap.createBitmap(newWidth, newHeight, newConfig);
|
||
|
Canvas canvas = new Canvas(outBitmap);
|
||
|
Paint paint = new Paint();
|
||
|
paint.setAntiAlias(true);
|
||
|
paint.setFilterBitmap(true);
|
||
|
canvas.drawBitmap(bitmap, null,
|
||
|
new RectF(0, 0, outBitmap.getWidth(), outBitmap.getHeight()), paint);
|
||
|
bitmap = outBitmap;
|
||
|
}
|
||
|
}
|
||
|
return bitmap;
|
||
|
}
|
||
|
|
||
|
private SessionHolder getHolder(PendingIntent pi, boolean createIfMissing) {
|
||
|
SessionHolder holder = mSessions.get(pi);
|
||
|
if (holder == null && createIfMissing) {
|
||
|
MediaSession session;
|
||
|
session = new MediaSession(mContext, TAG + "-" + pi.getCreatorPackage());
|
||
|
session.setActive(true);
|
||
|
holder = new SessionHolder(session, pi);
|
||
|
mSessions.put(pi, holder);
|
||
|
}
|
||
|
return holder;
|
||
|
}
|
||
|
|
||
|
private static void sendKeyEvent(PendingIntent pi, Context context, Intent intent) {
|
||
|
try {
|
||
|
pi.send(context, 0, intent);
|
||
|
} catch (CanceledException e) {
|
||
|
Log.e(TAG, "Error sending media key down event:", e);
|
||
|
// Don't bother sending up if down failed
|
||
|
return;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private static final class MediaButtonListener extends MediaSession.Callback {
|
||
|
private final PendingIntent mPendingIntent;
|
||
|
private final Context mContext;
|
||
|
|
||
|
public MediaButtonListener(PendingIntent pi, Context context) {
|
||
|
mPendingIntent = pi;
|
||
|
mContext = context;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public boolean onMediaButtonEvent(Intent mediaButtonIntent) {
|
||
|
MediaSessionLegacyHelper.sendKeyEvent(mPendingIntent, mContext, mediaButtonIntent);
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onPlay() {
|
||
|
sendKeyEvent(KeyEvent.KEYCODE_MEDIA_PLAY);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onPause() {
|
||
|
sendKeyEvent(KeyEvent.KEYCODE_MEDIA_PAUSE);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onSkipToNext() {
|
||
|
sendKeyEvent(KeyEvent.KEYCODE_MEDIA_NEXT);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onSkipToPrevious() {
|
||
|
sendKeyEvent(KeyEvent.KEYCODE_MEDIA_PREVIOUS);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onFastForward() {
|
||
|
sendKeyEvent(KeyEvent.KEYCODE_MEDIA_FAST_FORWARD);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onRewind() {
|
||
|
sendKeyEvent(KeyEvent.KEYCODE_MEDIA_REWIND);
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onStop() {
|
||
|
sendKeyEvent(KeyEvent.KEYCODE_MEDIA_STOP);
|
||
|
}
|
||
|
|
||
|
private void sendKeyEvent(int keyCode) {
|
||
|
KeyEvent ke = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
|
||
|
Intent intent = new Intent(Intent.ACTION_MEDIA_BUTTON);
|
||
|
intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
|
||
|
|
||
|
intent.putExtra(Intent.EXTRA_KEY_EVENT, ke);
|
||
|
MediaSessionLegacyHelper.sendKeyEvent(mPendingIntent, mContext, intent);
|
||
|
|
||
|
ke = new KeyEvent(KeyEvent.ACTION_UP, keyCode);
|
||
|
intent.putExtra(Intent.EXTRA_KEY_EVENT, ke);
|
||
|
MediaSessionLegacyHelper.sendKeyEvent(mPendingIntent, mContext, intent);
|
||
|
|
||
|
if (DEBUG) {
|
||
|
Log.d(TAG, "Sent " + keyCode + " to pending intent " + mPendingIntent);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private class SessionHolder {
|
||
|
public final MediaSession mSession;
|
||
|
public final PendingIntent mPi;
|
||
|
public MediaButtonListener mMediaButtonListener;
|
||
|
public MediaSession.Callback mRccListener;
|
||
|
public int mFlags;
|
||
|
|
||
|
public SessionCallback mCb;
|
||
|
|
||
|
public SessionHolder(MediaSession session, PendingIntent pi) {
|
||
|
mSession = session;
|
||
|
mPi = pi;
|
||
|
}
|
||
|
|
||
|
public void update() {
|
||
|
if (mMediaButtonListener == null && mRccListener == null) {
|
||
|
mSession.setCallback(null);
|
||
|
mSession.release();
|
||
|
mCb = null;
|
||
|
mSessions.remove(mPi);
|
||
|
} else if (mCb == null) {
|
||
|
mCb = new SessionCallback();
|
||
|
Handler handler = new Handler(Looper.getMainLooper());
|
||
|
mSession.setCallback(mCb, handler);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private class SessionCallback extends MediaSession.Callback {
|
||
|
|
||
|
@Override
|
||
|
public boolean onMediaButtonEvent(Intent mediaButtonIntent) {
|
||
|
if (mMediaButtonListener != null) {
|
||
|
mMediaButtonListener.onMediaButtonEvent(mediaButtonIntent);
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onPlay() {
|
||
|
if (mMediaButtonListener != null) {
|
||
|
mMediaButtonListener.onPlay();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onPause() {
|
||
|
if (mMediaButtonListener != null) {
|
||
|
mMediaButtonListener.onPause();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onSkipToNext() {
|
||
|
if (mMediaButtonListener != null) {
|
||
|
mMediaButtonListener.onSkipToNext();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onSkipToPrevious() {
|
||
|
if (mMediaButtonListener != null) {
|
||
|
mMediaButtonListener.onSkipToPrevious();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onFastForward() {
|
||
|
if (mMediaButtonListener != null) {
|
||
|
mMediaButtonListener.onFastForward();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onRewind() {
|
||
|
if (mMediaButtonListener != null) {
|
||
|
mMediaButtonListener.onRewind();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onStop() {
|
||
|
if (mMediaButtonListener != null) {
|
||
|
mMediaButtonListener.onStop();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onSeekTo(long pos) {
|
||
|
if (mRccListener != null) {
|
||
|
mRccListener.onSeekTo(pos);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public void onSetRating(Rating rating) {
|
||
|
if (mRccListener != null) {
|
||
|
mRccListener.onSetRating(rating);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|