Java tutorial
package android.support.v4.media.session; import android.app.PendingIntent; import android.content.Context; import android.os.Build.VERSION; import android.os.Bundle; import android.os.Handler; import android.os.IBinder; import android.os.IBinder.DeathRecipient; import android.os.Looper; import android.os.Message; import android.os.RemoteException; import android.os.ResultReceiver; import android.support.v4.media.MediaMetadataCompat; import android.support.v4.media.RatingCompat; import android.support.v4.media.session.IMediaControllerCallback.Stub; import android.support.v4.media.session.MediaSessionCompat.QueueItem; import android.support.v4.media.session.MediaSessionCompat.Token; import android.support.v4.media.session.PlaybackStateCompat.CustomAction; import android.text.TextUtils; import android.util.Log; import android.view.KeyEvent; import java.util.ArrayList; import java.util.List; public final class MediaControllerCompat { private static final String TAG = "MediaControllerCompat"; private final MediaControllerImpl mImpl; private final Token mToken; public static abstract class Callback implements DeathRecipient { private final Object mCallbackObj; private MessageHandler mHandler; private boolean mRegistered; private class MessageHandler extends Handler { private static final int MSG_DESTROYED = 8; private static final int MSG_EVENT = 1; private static final int MSG_UPDATE_EXTRAS = 7; private static final int MSG_UPDATE_METADATA = 3; private static final int MSG_UPDATE_PLAYBACK_STATE = 2; private static final int MSG_UPDATE_QUEUE = 5; private static final int MSG_UPDATE_QUEUE_TITLE = 6; private static final int MSG_UPDATE_VOLUME = 4; public MessageHandler(Looper looper) { super(looper); } public void handleMessage(Message message) { if (Callback.this.mRegistered) { switch (message.what) { case MSG_EVENT /*1*/: Callback.this.onSessionEvent((String) message.obj, message.getData()); case MSG_UPDATE_PLAYBACK_STATE /*2*/: Callback.this.onPlaybackStateChanged((PlaybackStateCompat) message.obj); case MSG_UPDATE_METADATA /*3*/: Callback.this.onMetadataChanged((MediaMetadataCompat) message.obj); case MSG_UPDATE_VOLUME /*4*/: Callback.this.onAudioInfoChanged((PlaybackInfo) message.obj); case MSG_UPDATE_QUEUE /*5*/: Callback.this.onQueueChanged((List) message.obj); case MSG_UPDATE_QUEUE_TITLE /*6*/: Callback.this.onQueueTitleChanged((CharSequence) message.obj); case MSG_UPDATE_EXTRAS /*7*/: Callback.this.onExtrasChanged((Bundle) message.obj); case MSG_DESTROYED /*8*/: Callback.this.onSessionDestroyed(); default: } } } public void post(int i, Object obj, Bundle bundle) { obtainMessage(i, obj).sendToTarget(); } } private class StubApi21 implements android.support.v4.media.session.MediaControllerCompatApi21.Callback { private StubApi21() { } public void onSessionDestroyed() { Callback.this.onSessionDestroyed(); } public void onSessionEvent(String str, Bundle bundle) { Callback.this.onSessionEvent(str, bundle); } public void onPlaybackStateChanged(Object obj) { Callback.this.onPlaybackStateChanged(PlaybackStateCompat.fromPlaybackState(obj)); } public void onMetadataChanged(Object obj) { Callback.this.onMetadataChanged(MediaMetadataCompat.fromMediaMetadata(obj)); } } private class StubCompat extends Stub { private StubCompat() { } public void onEvent(String str, Bundle bundle) throws RemoteException { Callback.this.mHandler.post(1, str, bundle); } public void onSessionDestroyed() throws RemoteException { Callback.this.mHandler.post(8, null, null); } public void onPlaybackStateChanged(PlaybackStateCompat playbackStateCompat) throws RemoteException { Callback.this.mHandler.post(2, playbackStateCompat, null); } public void onMetadataChanged(MediaMetadataCompat mediaMetadataCompat) throws RemoteException { Callback.this.mHandler.post(3, mediaMetadataCompat, null); } public void onQueueChanged(List<QueueItem> list) throws RemoteException { Callback.this.mHandler.post(5, list, null); } public void onQueueTitleChanged(CharSequence charSequence) throws RemoteException { Callback.this.mHandler.post(6, charSequence, null); } public void onExtrasChanged(Bundle bundle) throws RemoteException { Callback.this.mHandler.post(7, bundle, null); } public void onVolumeInfoChanged(ParcelableVolumeInfo parcelableVolumeInfo) throws RemoteException { Object playbackInfo; if (parcelableVolumeInfo != null) { playbackInfo = new PlaybackInfo(parcelableVolumeInfo.volumeType, parcelableVolumeInfo.audioStream, parcelableVolumeInfo.controlType, parcelableVolumeInfo.maxVolume, parcelableVolumeInfo.currentVolume); } else { playbackInfo = null; } Callback.this.mHandler.post(4, playbackInfo, null); } } public Callback() { this.mRegistered = false; if (VERSION.SDK_INT >= 21) { this.mCallbackObj = MediaControllerCompatApi21.createCallback(new StubApi21()); } else { this.mCallbackObj = new StubCompat(); } } public void onSessionDestroyed() { } public void onSessionEvent(String str, Bundle bundle) { } public void onPlaybackStateChanged(PlaybackStateCompat playbackStateCompat) { } public void onMetadataChanged(MediaMetadataCompat mediaMetadataCompat) { } public void onQueueChanged(List<QueueItem> list) { } public void onQueueTitleChanged(CharSequence charSequence) { } public void onExtrasChanged(Bundle bundle) { } public void onAudioInfoChanged(PlaybackInfo playbackInfo) { } public void binderDied() { onSessionDestroyed(); } private void setHandler(Handler handler) { this.mHandler = new MessageHandler(handler.getLooper()); } } interface MediaControllerImpl { void adjustVolume(int i, int i2); boolean dispatchMediaButtonEvent(KeyEvent keyEvent); Bundle getExtras(); long getFlags(); Object getMediaController(); MediaMetadataCompat getMetadata(); String getPackageName(); PlaybackInfo getPlaybackInfo(); PlaybackStateCompat getPlaybackState(); List<QueueItem> getQueue(); CharSequence getQueueTitle(); int getRatingType(); PendingIntent getSessionActivity(); TransportControls getTransportControls(); void registerCallback(Callback callback, Handler handler); void sendCommand(String str, Bundle bundle, ResultReceiver resultReceiver); void setVolumeTo(int i, int i2); void unregisterCallback(Callback callback); } static class MediaControllerImplApi21 implements MediaControllerImpl { private final Object mControllerObj; public MediaControllerImplApi21(Context context, MediaSessionCompat mediaSessionCompat) { this.mControllerObj = MediaControllerCompatApi21.fromToken(context, mediaSessionCompat.getSessionToken().getToken()); } public MediaControllerImplApi21(Context context, Token token) throws RemoteException { this.mControllerObj = MediaControllerCompatApi21.fromToken(context, token.getToken()); if (this.mControllerObj == null) { throw new RemoteException(); } } public void registerCallback(Callback callback, Handler handler) { MediaControllerCompatApi21.registerCallback(this.mControllerObj, callback.mCallbackObj, handler); } public void unregisterCallback(Callback callback) { MediaControllerCompatApi21.unregisterCallback(this.mControllerObj, callback.mCallbackObj); } public boolean dispatchMediaButtonEvent(KeyEvent keyEvent) { return MediaControllerCompatApi21.dispatchMediaButtonEvent(this.mControllerObj, keyEvent); } public TransportControls getTransportControls() { Object transportControls = MediaControllerCompatApi21.getTransportControls(this.mControllerObj); return transportControls != null ? new TransportControlsApi21(transportControls) : null; } public PlaybackStateCompat getPlaybackState() { Object playbackState = MediaControllerCompatApi21.getPlaybackState(this.mControllerObj); return playbackState != null ? PlaybackStateCompat.fromPlaybackState(playbackState) : null; } public MediaMetadataCompat getMetadata() { Object metadata = MediaControllerCompatApi21.getMetadata(this.mControllerObj); return metadata != null ? MediaMetadataCompat.fromMediaMetadata(metadata) : null; } public List<QueueItem> getQueue() { List<Object> queue = MediaControllerCompatApi21.getQueue(this.mControllerObj); if (queue == null) { return null; } List<QueueItem> arrayList = new ArrayList(); for (Object obtain : queue) { arrayList.add(QueueItem.obtain(obtain)); } return arrayList; } public CharSequence getQueueTitle() { return MediaControllerCompatApi21.getQueueTitle(this.mControllerObj); } public Bundle getExtras() { return MediaControllerCompatApi21.getExtras(this.mControllerObj); } public int getRatingType() { return MediaControllerCompatApi21.getRatingType(this.mControllerObj); } public long getFlags() { return MediaControllerCompatApi21.getFlags(this.mControllerObj); } public PlaybackInfo getPlaybackInfo() { Object playbackInfo = MediaControllerCompatApi21.getPlaybackInfo(this.mControllerObj); return playbackInfo != null ? new PlaybackInfo( android.support.v4.media.session.MediaControllerCompatApi21.PlaybackInfo .getPlaybackType(playbackInfo), android.support.v4.media.session.MediaControllerCompatApi21.PlaybackInfo .getLegacyAudioStream(playbackInfo), android.support.v4.media.session.MediaControllerCompatApi21.PlaybackInfo .getVolumeControl(playbackInfo), android.support.v4.media.session.MediaControllerCompatApi21.PlaybackInfo .getMaxVolume(playbackInfo), android.support.v4.media.session.MediaControllerCompatApi21.PlaybackInfo .getCurrentVolume(playbackInfo)) : null; } public PendingIntent getSessionActivity() { return MediaControllerCompatApi21.getSessionActivity(this.mControllerObj); } public void setVolumeTo(int i, int i2) { MediaControllerCompatApi21.setVolumeTo(this.mControllerObj, i, i2); } public void adjustVolume(int i, int i2) { MediaControllerCompatApi21.adjustVolume(this.mControllerObj, i, i2); } public void sendCommand(String str, Bundle bundle, ResultReceiver resultReceiver) { MediaControllerCompatApi21.sendCommand(this.mControllerObj, str, bundle, resultReceiver); } public String getPackageName() { return MediaControllerCompatApi21.getPackageName(this.mControllerObj); } public Object getMediaController() { return this.mControllerObj; } } static class MediaControllerImplBase implements MediaControllerImpl { private IMediaSession mBinder; private Token mToken; private TransportControls mTransportControls; public MediaControllerImplBase(Token token) { this.mToken = token; this.mBinder = IMediaSession.Stub.asInterface((IBinder) token.getToken()); } public void registerCallback(Callback callback, Handler handler) { if (callback == null) { throw new IllegalArgumentException("callback may not be null."); } try { this.mBinder.asBinder().linkToDeath(callback, 0); this.mBinder.registerCallbackListener((IMediaControllerCallback) callback.mCallbackObj); callback.setHandler(handler); callback.mRegistered = true; } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in registerCallback. " + e); callback.onSessionDestroyed(); } } public void unregisterCallback(Callback callback) { if (callback == null) { throw new IllegalArgumentException("callback may not be null."); } try { this.mBinder.unregisterCallbackListener((IMediaControllerCallback) callback.mCallbackObj); this.mBinder.asBinder().unlinkToDeath(callback, 0); callback.mRegistered = false; } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in unregisterCallback. " + e); } } public boolean dispatchMediaButtonEvent(KeyEvent keyEvent) { if (keyEvent == null) { throw new IllegalArgumentException("event may not be null."); } try { this.mBinder.sendMediaButton(keyEvent); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in dispatchMediaButtonEvent. " + e); } return false; } public TransportControls getTransportControls() { if (this.mTransportControls == null) { this.mTransportControls = new TransportControlsBase(this.mBinder); } return this.mTransportControls; } public PlaybackStateCompat getPlaybackState() { try { return this.mBinder.getPlaybackState(); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in getPlaybackState. " + e); return null; } } public MediaMetadataCompat getMetadata() { try { return this.mBinder.getMetadata(); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in getMetadata. " + e); return null; } } public List<QueueItem> getQueue() { try { return this.mBinder.getQueue(); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in getQueue. " + e); return null; } } public CharSequence getQueueTitle() { try { return this.mBinder.getQueueTitle(); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in getQueueTitle. " + e); return null; } } public Bundle getExtras() { try { return this.mBinder.getExtras(); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in getExtras. " + e); return null; } } public int getRatingType() { try { return this.mBinder.getRatingType(); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in getRatingType. " + e); return 0; } } public long getFlags() { try { return this.mBinder.getFlags(); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in getFlags. " + e); return 0; } } public PlaybackInfo getPlaybackInfo() { try { ParcelableVolumeInfo volumeAttributes = this.mBinder.getVolumeAttributes(); return new PlaybackInfo(volumeAttributes.volumeType, volumeAttributes.audioStream, volumeAttributes.controlType, volumeAttributes.maxVolume, volumeAttributes.currentVolume); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in getPlaybackInfo. " + e); return null; } } public PendingIntent getSessionActivity() { try { return this.mBinder.getLaunchPendingIntent(); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in getSessionActivity. " + e); return null; } } public void setVolumeTo(int i, int i2) { try { this.mBinder.setVolumeTo(i, i2, null); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in setVolumeTo. " + e); } } public void adjustVolume(int i, int i2) { try { this.mBinder.adjustVolume(i, i2, null); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in adjustVolume. " + e); } } public void sendCommand(String str, Bundle bundle, ResultReceiver resultReceiver) { try { this.mBinder.sendCommand(str, bundle, new ResultReceiverWrapper(resultReceiver)); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in sendCommand. " + e); } } public String getPackageName() { try { return this.mBinder.getPackageName(); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in getPackageName. " + e); return null; } } public Object getMediaController() { return null; } } public static final class PlaybackInfo { public static final int PLAYBACK_TYPE_LOCAL = 1; public static final int PLAYBACK_TYPE_REMOTE = 2; private final int mAudioStream; private final int mCurrentVolume; private final int mMaxVolume; private final int mPlaybackType; private final int mVolumeControl; PlaybackInfo(int i, int i2, int i3, int i4, int i5) { this.mPlaybackType = i; this.mAudioStream = i2; this.mVolumeControl = i3; this.mMaxVolume = i4; this.mCurrentVolume = i5; } public int getPlaybackType() { return this.mPlaybackType; } public int getAudioStream() { return this.mAudioStream; } public int getVolumeControl() { return this.mVolumeControl; } public int getMaxVolume() { return this.mMaxVolume; } public int getCurrentVolume() { return this.mCurrentVolume; } } public static abstract class TransportControls { public abstract void fastForward(); public abstract void pause(); public abstract void play(); public abstract void playFromMediaId(String str, Bundle bundle); public abstract void playFromSearch(String str, Bundle bundle); public abstract void rewind(); public abstract void seekTo(long j); public abstract void sendCustomAction(CustomAction customAction, Bundle bundle); public abstract void sendCustomAction(String str, Bundle bundle); public abstract void setRating(RatingCompat ratingCompat); public abstract void skipToNext(); public abstract void skipToPrevious(); public abstract void skipToQueueItem(long j); public abstract void stop(); TransportControls() { } } static class TransportControlsApi21 extends TransportControls { private final Object mControlsObj; public TransportControlsApi21(Object obj) { this.mControlsObj = obj; } public void play() { android.support.v4.media.session.MediaControllerCompatApi21.TransportControls.play(this.mControlsObj); } public void pause() { android.support.v4.media.session.MediaControllerCompatApi21.TransportControls.pause(this.mControlsObj); } public void stop() { android.support.v4.media.session.MediaControllerCompatApi21.TransportControls.stop(this.mControlsObj); } public void seekTo(long j) { android.support.v4.media.session.MediaControllerCompatApi21.TransportControls.seekTo(this.mControlsObj, j); } public void fastForward() { android.support.v4.media.session.MediaControllerCompatApi21.TransportControls .fastForward(this.mControlsObj); } public void rewind() { android.support.v4.media.session.MediaControllerCompatApi21.TransportControls.rewind(this.mControlsObj); } public void skipToNext() { android.support.v4.media.session.MediaControllerCompatApi21.TransportControls .skipToNext(this.mControlsObj); } public void skipToPrevious() { android.support.v4.media.session.MediaControllerCompatApi21.TransportControls .skipToPrevious(this.mControlsObj); } public void setRating(RatingCompat ratingCompat) { android.support.v4.media.session.MediaControllerCompatApi21.TransportControls .setRating(this.mControlsObj, ratingCompat != null ? ratingCompat.getRating() : null); } public void playFromMediaId(String str, Bundle bundle) { android.support.v4.media.session.MediaControllerCompatApi21.TransportControls .playFromMediaId(this.mControlsObj, str, bundle); } public void playFromSearch(String str, Bundle bundle) { android.support.v4.media.session.MediaControllerCompatApi21.TransportControls .playFromSearch(this.mControlsObj, str, bundle); } public void skipToQueueItem(long j) { android.support.v4.media.session.MediaControllerCompatApi21.TransportControls .skipToQueueItem(this.mControlsObj, j); } public void sendCustomAction(CustomAction customAction, Bundle bundle) { android.support.v4.media.session.MediaControllerCompatApi21.TransportControls .sendCustomAction(this.mControlsObj, customAction.getAction(), bundle); } public void sendCustomAction(String str, Bundle bundle) { android.support.v4.media.session.MediaControllerCompatApi21.TransportControls .sendCustomAction(this.mControlsObj, str, bundle); } } static class TransportControlsBase extends TransportControls { private IMediaSession mBinder; public TransportControlsBase(IMediaSession iMediaSession) { this.mBinder = iMediaSession; } public void play() { try { this.mBinder.play(); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in play. " + e); } } public void playFromMediaId(String str, Bundle bundle) { try { this.mBinder.playFromMediaId(str, bundle); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in playFromMediaId. " + e); } } public void playFromSearch(String str, Bundle bundle) { try { this.mBinder.playFromSearch(str, bundle); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in playFromSearch. " + e); } } public void skipToQueueItem(long j) { try { this.mBinder.skipToQueueItem(j); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in skipToQueueItem. " + e); } } public void pause() { try { this.mBinder.pause(); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in pause. " + e); } } public void stop() { try { this.mBinder.stop(); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in stop. " + e); } } public void seekTo(long j) { try { this.mBinder.seekTo(j); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in seekTo. " + e); } } public void fastForward() { try { this.mBinder.fastForward(); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in fastForward. " + e); } } public void skipToNext() { try { this.mBinder.next(); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in skipToNext. " + e); } } public void rewind() { try { this.mBinder.rewind(); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in rewind. " + e); } } public void skipToPrevious() { try { this.mBinder.previous(); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in skipToPrevious. " + e); } } public void setRating(RatingCompat ratingCompat) { try { this.mBinder.rate(ratingCompat); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in setRating. " + e); } } public void sendCustomAction(CustomAction customAction, Bundle bundle) { sendCustomAction(customAction.getAction(), bundle); } public void sendCustomAction(String str, Bundle bundle) { try { this.mBinder.sendCustomAction(str, bundle); } catch (RemoteException e) { Log.e(MediaControllerCompat.TAG, "Dead object in sendCustomAction. " + e); } } } public MediaControllerCompat(Context context, MediaSessionCompat mediaSessionCompat) { if (mediaSessionCompat == null) { throw new IllegalArgumentException("session must not be null"); } this.mToken = mediaSessionCompat.getSessionToken(); if (VERSION.SDK_INT >= 21) { this.mImpl = new MediaControllerImplApi21(context, mediaSessionCompat); } else { this.mImpl = new MediaControllerImplBase(this.mToken); } } public MediaControllerCompat(Context context, Token token) throws RemoteException { if (token == null) { throw new IllegalArgumentException("sessionToken must not be null"); } this.mToken = token; if (VERSION.SDK_INT >= 21) { this.mImpl = new MediaControllerImplApi21(context, token); } else { this.mImpl = new MediaControllerImplBase(this.mToken); } } public TransportControls getTransportControls() { return this.mImpl.getTransportControls(); } public boolean dispatchMediaButtonEvent(KeyEvent keyEvent) { if (keyEvent != null) { return this.mImpl.dispatchMediaButtonEvent(keyEvent); } throw new IllegalArgumentException("KeyEvent may not be null"); } public PlaybackStateCompat getPlaybackState() { return this.mImpl.getPlaybackState(); } public MediaMetadataCompat getMetadata() { return this.mImpl.getMetadata(); } public List<QueueItem> getQueue() { return this.mImpl.getQueue(); } public CharSequence getQueueTitle() { return this.mImpl.getQueueTitle(); } public Bundle getExtras() { return this.mImpl.getExtras(); } public int getRatingType() { return this.mImpl.getRatingType(); } public long getFlags() { return this.mImpl.getFlags(); } public PlaybackInfo getPlaybackInfo() { return this.mImpl.getPlaybackInfo(); } public PendingIntent getSessionActivity() { return this.mImpl.getSessionActivity(); } public Token getSessionToken() { return this.mToken; } public void setVolumeTo(int i, int i2) { this.mImpl.setVolumeTo(i, i2); } public void adjustVolume(int i, int i2) { this.mImpl.adjustVolume(i, i2); } public void registerCallback(Callback callback) { registerCallback(callback, null); } public void registerCallback(Callback callback, Handler handler) { if (callback == null) { throw new IllegalArgumentException("callback cannot be null"); } if (handler == null) { handler = new Handler(); } this.mImpl.registerCallback(callback, handler); } public void unregisterCallback(Callback callback) { if (callback == null) { throw new IllegalArgumentException("callback cannot be null"); } this.mImpl.unregisterCallback(callback); } public void sendCommand(String str, Bundle bundle, ResultReceiver resultReceiver) { if (TextUtils.isEmpty(str)) { throw new IllegalArgumentException("command cannot be null or empty"); } this.mImpl.sendCommand(str, bundle, resultReceiver); } public String getPackageName() { return this.mImpl.getPackageName(); } public Object getMediaController() { return this.mImpl.getMediaController(); } }