diff --git a/api/system-current.txt b/api/system-current.txt
index 2088eaf..33f7a00 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -3530,6 +3530,76 @@
     method public void unregisterCallback(@NonNull android.media.session.ControllerCallbackLink);
   }
 
+  public abstract static class MediaSession.Callback {
+    method public void onSetMediaButtonEventDelegate(@NonNull android.media.session.MediaSessionEngine.MediaButtonEventDelegate);
+  }
+
+  public final class MediaSessionEngine implements java.lang.AutoCloseable {
+    ctor public MediaSessionEngine(@NonNull android.content.Context, @NonNull android.media.session.SessionLink, @NonNull android.media.session.SessionCallbackLink, @NonNull android.media.session.MediaSessionEngine.CallbackStub, int);
+    method public void close();
+    method public String getCallingPackage();
+    method @NonNull public android.media.session.MediaController getController();
+    method @NonNull public android.media.session.MediaSessionManager.RemoteUserInfo getCurrentControllerInfo();
+    method @NonNull public android.media.session.MediaSession.Token getSessionToken();
+    method public boolean isActive();
+    method public static boolean isActiveState(int);
+    method public void sendSessionEvent(@NonNull String, @Nullable android.os.Bundle);
+    method public void setActive(boolean);
+    method public void setCallback(@Nullable android.media.session.MediaSession.Callback);
+    method public void setCallback(@Nullable android.media.session.MediaSession.Callback, @NonNull android.os.Handler);
+    method public void setExtras(@Nullable android.os.Bundle);
+    method public void setFlags(int);
+    method public void setMediaButtonReceiver(@Nullable android.app.PendingIntent);
+    method public void setMetadata(@Nullable android.media.MediaMetadata);
+    method public void setPlaybackState(@Nullable android.media.session.PlaybackState);
+    method public void setPlaybackToLocal(android.media.AudioAttributes);
+    method public void setPlaybackToRemote(@NonNull android.media.VolumeProvider);
+    method public void setQueue(@Nullable java.util.List<android.media.session.MediaSession.QueueItem>);
+    method public void setQueueTitle(@Nullable CharSequence);
+    method public void setRatingType(int);
+    method public void setSessionActivity(@Nullable android.app.PendingIntent);
+  }
+
+  public static final class MediaSessionEngine.CallbackStub {
+    ctor public MediaSessionEngine.CallbackStub();
+    method public void onAdjustVolume(String, int, int, android.media.session.ControllerCallbackLink, int);
+    method public void onCommand(String, int, int, android.media.session.ControllerCallbackLink, String, android.os.Bundle, android.os.ResultReceiver);
+    method public void onCustomAction(String, int, int, android.media.session.ControllerCallbackLink, String, android.os.Bundle);
+    method public void onFastForward(String, int, int, android.media.session.ControllerCallbackLink);
+    method public void onMediaButton(String, int, int, android.content.Intent, int, android.os.ResultReceiver);
+    method public void onMediaButtonFromController(String, int, int, android.media.session.ControllerCallbackLink, android.content.Intent);
+    method public void onNext(String, int, int, android.media.session.ControllerCallbackLink);
+    method public void onPause(String, int, int, android.media.session.ControllerCallbackLink);
+    method public void onPlay(String, int, int, android.media.session.ControllerCallbackLink);
+    method public void onPlayFromMediaId(String, int, int, android.media.session.ControllerCallbackLink, String, android.os.Bundle);
+    method public void onPlayFromSearch(String, int, int, android.media.session.ControllerCallbackLink, String, android.os.Bundle);
+    method public void onPlayFromUri(String, int, int, android.media.session.ControllerCallbackLink, android.net.Uri, android.os.Bundle);
+    method public void onPrepare(String, int, int, android.media.session.ControllerCallbackLink);
+    method public void onPrepareFromMediaId(String, int, int, android.media.session.ControllerCallbackLink, String, android.os.Bundle);
+    method public void onPrepareFromSearch(String, int, int, android.media.session.ControllerCallbackLink, String, android.os.Bundle);
+    method public void onPrepareFromUri(String, int, int, android.media.session.ControllerCallbackLink, android.net.Uri, android.os.Bundle);
+    method public void onPrevious(String, int, int, android.media.session.ControllerCallbackLink);
+    method public void onRate(String, int, int, android.media.session.ControllerCallbackLink, android.media.Rating);
+    method public void onRewind(String, int, int, android.media.session.ControllerCallbackLink);
+    method public void onSeekTo(String, int, int, android.media.session.ControllerCallbackLink, long);
+    method public void onSetVolumeTo(String, int, int, android.media.session.ControllerCallbackLink, int);
+    method public void onSkipToTrack(String, int, int, android.media.session.ControllerCallbackLink, long);
+    method public void onStop(String, int, int, android.media.session.ControllerCallbackLink);
+  }
+
+  public static interface MediaSessionEngine.MediaButtonEventDelegate {
+    method public boolean onMediaButtonIntent(android.content.Intent);
+  }
+
+  public static final class MediaSessionEngine.QueueItem {
+    ctor public MediaSessionEngine.QueueItem(android.media.MediaDescription, long);
+    ctor public MediaSessionEngine.QueueItem(android.os.Parcel);
+    method public android.media.MediaDescription getDescription();
+    method public long getQueueId();
+    method public void writeToParcel(android.os.Parcel, int);
+    field public static final int UNKNOWN_ID = -1; // 0xffffffff
+  }
+
   public final class MediaSessionManager {
     method @RequiresPermission(android.Manifest.permission.SET_MEDIA_KEY_LISTENER) public void setOnMediaKeyListener(android.media.session.MediaSessionManager.OnMediaKeyListener, @Nullable android.os.Handler);
     method @RequiresPermission(android.Manifest.permission.SET_VOLUME_KEY_LONG_PRESS_LISTENER) public void setOnVolumeKeyLongPressListener(android.media.session.MediaSessionManager.OnVolumeKeyLongPressListener, @Nullable android.os.Handler);
diff --git a/media/java/android/media/session/ControllerCallbackLink.java b/media/java/android/media/session/ControllerCallbackLink.java
index 95e19d2..28845e4 100644
--- a/media/java/android/media/session/ControllerCallbackLink.java
+++ b/media/java/android/media/session/ControllerCallbackLink.java
@@ -254,7 +254,7 @@
 
         @Override
         public void notifyPlaybackStateChanged(PlaybackState state) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onPlaybackStateChanged(state);
@@ -265,7 +265,7 @@
 
         @Override
         public void notifyMetadataChanged(MediaMetadata metadata) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onMetadataChanged(metadata);
@@ -276,7 +276,7 @@
 
         @Override
         public void notifyQueueChanged(List<QueueItem> queue) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onQueueChanged(queue);
@@ -287,7 +287,7 @@
 
         @Override
         public void notifyQueueTitleChanged(CharSequence title) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onQueueTitleChanged(title);
@@ -303,7 +303,7 @@
 
         @Override
         public void notifyVolumeInfoChanged(PlaybackInfo info) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onVolumeInfoChanged(info);
@@ -312,7 +312,7 @@
             }
         }
 
-        private void ensureMediasControlPermission() {
+        private void ensureMediaControlPermission() {
             // Allow API calls from the System UI
             if (mContext.checkCallingPermission(android.Manifest.permission.STATUS_BAR_SERVICE)
                     == PackageManager.PERMISSION_GRANTED) {
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 9d537c8..057c9cb 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -117,7 +117,7 @@
      * @param token The token for the session.
      */
     public MediaController(@NonNull Context context, @NonNull MediaSession.Token token) {
-        this(context, token.getBinder());
+        this(context, token.getControllerLink());
     }
 
     /**
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index f02d9ba..eda913e 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -19,6 +19,7 @@
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.annotation.UnsupportedAppUsage;
 import android.app.Activity;
 import android.app.PendingIntent;
@@ -33,23 +34,15 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.os.ResultReceiver;
 import android.service.media.MediaBrowserService;
 import android.text.TextUtils;
-import android.util.Log;
-import android.util.Pair;
-import android.view.KeyEvent;
-import android.view.ViewConfiguration;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.lang.ref.WeakReference;
 import java.util.List;
-import java.util.Objects;
 
 /**
  * Allows interaction with media controllers, volume keys, media buttons, and
@@ -74,7 +67,7 @@
  * MediaSession objects are thread safe.
  */
 public final class MediaSession {
-    private static final String TAG = "MediaSession";
+    static final String TAG = "MediaSession";
 
     /**
      * Set this flag on the session to indicate that it can handle media button
@@ -121,21 +114,11 @@
             FLAG_EXCLUSIVE_GLOBAL_PRIORITY })
     public @interface SessionFlags { }
 
-    private final Object mLock = new Object();
-    private final int mMaxBitmapSize;
+    private final MediaSessionEngine mImpl;
 
-    private final MediaSession.Token mSessionToken;
-    private final MediaController mController;
-    private final SessionLink mSessionLink;
-    private final SessionCallbackLink mCbStub;
-
-    // Do not change the name of mCallback. Support lib accesses this by using reflection.
+    // Do not change the name of mCallbackWrapper. Support lib accesses this by using reflection.
     @UnsupportedAppUsage
-    private CallbackMessageHandler mCallback;
-    private VolumeProvider mVolumeProvider;
-    private PlaybackState mPlaybackState;
-
-    private boolean mActive = false;
+    private Object mCallback;
 
     /**
      * Creates a new session. The session will automatically be registered with
@@ -153,15 +136,15 @@
         if (TextUtils.isEmpty(tag)) {
             throw new IllegalArgumentException("tag cannot be null or empty");
         }
-        mMaxBitmapSize = context.getResources().getDimensionPixelSize(
-                android.R.dimen.config_mediaMetadataBitmapMaxSize);
-        mCbStub = new SessionCallbackLink(context, new CallbackStub(this));
         MediaSessionManager manager = (MediaSessionManager) context
                 .getSystemService(Context.MEDIA_SESSION_SERVICE);
         try {
-            mSessionLink = manager.createSession(mCbStub, tag);
-            mSessionToken = new Token(mSessionLink.getController());
-            mController = new MediaController(context, mSessionToken);
+            MediaSessionEngine.CallbackStub cbStub = new MediaSessionEngine.CallbackStub();
+            SessionCallbackLink cbLink = new SessionCallbackLink(context, cbStub);
+            SessionLink sessionLink = manager.createSession(cbLink, tag);
+            mImpl = new MediaSessionEngine(context, sessionLink, cbLink, cbStub,
+                    context.getResources().getDimensionPixelSize(
+                            com.android.internal.R.dimen.config_mediaMetadataBitmapMaxSize));
         } catch (RuntimeException e) {
             throw new RuntimeException("Remote error creating session.", e);
         }
@@ -177,7 +160,7 @@
      * @param callback The callback object
      */
     public void setCallback(@Nullable Callback callback) {
-        setCallback(callback, null);
+        mImpl.setCallback(callback);
     }
 
     /**
@@ -190,24 +173,7 @@
      * @param handler The handler that events should be posted on.
      */
     public void setCallback(@Nullable Callback callback, @Nullable Handler handler) {
-        synchronized (mLock) {
-            if (mCallback != null) {
-                // We're updating the callback, clear the session from the old one.
-                mCallback.mCallback.mSession = null;
-                mCallback.removeCallbacksAndMessages(null);
-            }
-            if (callback == null) {
-                mCallback = null;
-                return;
-            }
-            if (handler == null) {
-                handler = new Handler();
-            }
-            callback.mSession = this;
-            CallbackMessageHandler msgHandler = new CallbackMessageHandler(handler.getLooper(),
-                    callback);
-            mCallback = msgHandler;
-        }
+        mImpl.setCallback(callback, handler);
     }
 
     /**
@@ -218,11 +184,7 @@
      * @param pi The intent to launch to show UI for this Session.
      */
     public void setSessionActivity(@Nullable PendingIntent pi) {
-        try {
-            mSessionLink.setLaunchPendingIntent(pi);
-        } catch (RuntimeException e) {
-            Log.wtf(TAG, "Failure in setLaunchPendingIntent.", e);
-        }
+        mImpl.setSessionActivity(pi);
     }
 
     /**
@@ -234,11 +196,7 @@
      * @param mbr The {@link PendingIntent} to send the media button event to.
      */
     public void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
-        try {
-            mSessionLink.setMediaButtonReceiver(mbr);
-        } catch (RuntimeException e) {
-            Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e);
-        }
+        mImpl.setMediaButtonReceiver(mbr);
     }
 
     /**
@@ -247,11 +205,7 @@
      * @param flags The flags to set for this session.
      */
     public void setFlags(@SessionFlags int flags) {
-        try {
-            mSessionLink.setFlags(flags);
-        } catch (RuntimeException e) {
-            Log.wtf(TAG, "Failure in setFlags.", e);
-        }
+        mImpl.setFlags(flags);
     }
 
     /**
@@ -266,14 +220,7 @@
      * @param attributes The {@link AudioAttributes} for this session's audio.
      */
     public void setPlaybackToLocal(AudioAttributes attributes) {
-        if (attributes == null) {
-            throw new IllegalArgumentException("Attributes cannot be null for local playback.");
-        }
-        try {
-            mSessionLink.setPlaybackToLocal(attributes);
-        } catch (RuntimeException e) {
-            Log.wtf(TAG, "Failure in setPlaybackToLocal.", e);
-        }
+        mImpl.setPlaybackToLocal(attributes);
     }
 
     /**
@@ -288,26 +235,7 @@
      *            not be null.
      */
     public void setPlaybackToRemote(@NonNull VolumeProvider volumeProvider) {
-        if (volumeProvider == null) {
-            throw new IllegalArgumentException("volumeProvider may not be null!");
-        }
-        synchronized (mLock) {
-            mVolumeProvider = volumeProvider;
-        }
-        volumeProvider.setCallback(new VolumeProvider.Callback() {
-            @Override
-            public void onVolumeChanged(VolumeProvider volumeProvider) {
-                notifyRemoteVolumeChanged(volumeProvider);
-            }
-        });
-
-        try {
-            mSessionLink.setPlaybackToRemote(volumeProvider.getVolumeControl(),
-                    volumeProvider.getMaxVolume());
-            mSessionLink.setCurrentVolume(volumeProvider.getCurrentVolume());
-        } catch (RuntimeException e) {
-            Log.wtf(TAG, "Failure in setPlaybackToRemote.", e);
-        }
+        mImpl.setPlaybackToRemote(volumeProvider);
     }
 
     /**
@@ -319,15 +247,7 @@
      * @param active Whether this session is active or not.
      */
     public void setActive(boolean active) {
-        if (mActive == active) {
-            return;
-        }
-        try {
-            mSessionLink.setActive(active);
-            mActive = active;
-        } catch (RuntimeException e) {
-            Log.wtf(TAG, "Failure in setActive.", e);
-        }
+        mImpl.setActive(active);
     }
 
     /**
@@ -336,7 +256,7 @@
      * @return True if the session is active, false otherwise.
      */
     public boolean isActive() {
-        return mActive;
+        return mImpl.isActive();
     }
 
     /**
@@ -348,14 +268,7 @@
      * @param extras Any extras included with the event
      */
     public void sendSessionEvent(@NonNull String event, @Nullable Bundle extras) {
-        if (TextUtils.isEmpty(event)) {
-            throw new IllegalArgumentException("event cannot be null or empty");
-        }
-        try {
-            mSessionLink.sendEvent(event, extras);
-        } catch (RuntimeException e) {
-            Log.wtf(TAG, "Error sending event", e);
-        }
+        mImpl.sendSessionEvent(event, extras);
     }
 
     /**
@@ -364,11 +277,7 @@
      * but it must be released if your activity or service is being destroyed.
      */
     public void release() {
-        try {
-            mSessionLink.destroySession();
-        } catch (RuntimeException e) {
-            Log.wtf(TAG, "Error releasing session: ", e);
-        }
+        mImpl.close();
     }
 
     /**
@@ -380,7 +289,7 @@
      *         session
      */
     public @NonNull Token getSessionToken() {
-        return mSessionToken;
+        return mImpl.getSessionToken();
     }
 
     /**
@@ -390,7 +299,7 @@
      * @return A controller for this session.
      */
     public @NonNull MediaController getController() {
-        return mController;
+        return mImpl.getController();
     }
 
     /**
@@ -399,12 +308,7 @@
      * @param state The current state of playback
      */
     public void setPlaybackState(@Nullable PlaybackState state) {
-        mPlaybackState = state;
-        try {
-            mSessionLink.setPlaybackState(state);
-        } catch (RuntimeException e) {
-            Log.wtf(TAG, "Dead object in setPlaybackState.", e);
-        }
+        mImpl.setPlaybackState(state);
     }
 
     /**
@@ -416,24 +320,7 @@
      * @see android.media.MediaMetadata.Builder#putBitmap
      */
     public void setMetadata(@Nullable MediaMetadata metadata) {
-        long duration = -1;
-        int fields = 0;
-        MediaDescription description = null;
-        if (metadata != null) {
-            metadata = (new MediaMetadata.Builder(metadata, mMaxBitmapSize)).build();
-            if (metadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) {
-                duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
-            }
-            fields = metadata.size();
-            description = metadata.getDescription();
-        }
-        String metadataDescription = "size=" + fields + ", description=" + description;
-
-        try {
-            mSessionLink.setMetadata(metadata, duration, metadataDescription);
-        } catch (RuntimeException e) {
-            Log.wtf(TAG, "Dead object in setPlaybackState.", e);
-        }
+        mImpl.setMetadata(metadata);
     }
 
     /**
@@ -448,11 +335,7 @@
      * @param queue A list of items in the play queue.
      */
     public void setQueue(@Nullable List<QueueItem> queue) {
-        try {
-            mSessionLink.setQueue(queue);
-        } catch (RuntimeException e) {
-            Log.wtf("Dead object in setQueue.", e);
-        }
+        mImpl.setQueue(queue);
     }
 
     /**
@@ -463,11 +346,7 @@
      * @param title The title of the play queue.
      */
     public void setQueueTitle(@Nullable CharSequence title) {
-        try {
-            mSessionLink.setQueueTitle(title);
-        } catch (RuntimeException e) {
-            Log.wtf("Dead object in setQueueTitle.", e);
-        }
+        mImpl.setQueueTitle(title);
     }
 
     /**
@@ -484,11 +363,7 @@
      * </ul>
      */
     public void setRatingType(@Rating.Style int type) {
-        try {
-            mSessionLink.setRatingType(type);
-        } catch (RuntimeException e) {
-            Log.e(TAG, "Error in setRatingType.", e);
-        }
+        mImpl.setRatingType(type);
     }
 
     /**
@@ -499,11 +374,7 @@
      * @param extras The extras associated with the {@link MediaSession}.
      */
     public void setExtras(@Nullable Bundle extras) {
-        try {
-            mSessionLink.setExtras(extras);
-        } catch (RuntimeException e) {
-            Log.wtf("Dead object in setExtras.", e);
-        }
+        mImpl.setExtras(extras);
     }
 
     /**
@@ -515,11 +386,7 @@
      * @see MediaSessionManager#isTrustedForMediaControl(RemoteUserInfo)
      */
     public final @NonNull RemoteUserInfo getCurrentControllerInfo() {
-        if (mCallback == null || mCallback.mCurrentControllerInfo == null) {
-            throw new IllegalStateException(
-                    "This should be called inside of MediaSession.Callback methods");
-        }
-        return mCallback.mCurrentControllerInfo;
+        return mImpl.getCurrentControllerInfo();
     }
 
     /**
@@ -529,17 +396,7 @@
      * @hide
      */
     public void notifyRemoteVolumeChanged(VolumeProvider provider) {
-        synchronized (mLock) {
-            if (provider == null || provider != mVolumeProvider) {
-                Log.w(TAG, "Received update from stale volume provider");
-                return;
-            }
-        }
-        try {
-            mSessionLink.setCurrentVolume(provider.getCurrentVolume());
-        } catch (RuntimeException e) {
-            Log.e(TAG, "Error in notifyVolumeChanged", e);
-        }
+        mImpl.notifyRemoteVolumeChanged(provider);
     }
 
     /**
@@ -551,119 +408,7 @@
      */
     @UnsupportedAppUsage
     public String getCallingPackage() {
-        if (mCallback != null && mCallback.mCurrentControllerInfo != null) {
-            return mCallback.mCurrentControllerInfo.getPackageName();
-        }
-        return null;
-    }
-
-    private void dispatchPrepare(RemoteUserInfo caller) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PREPARE, null, null);
-    }
-
-    private void dispatchPrepareFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_MEDIA_ID, mediaId, extras);
-    }
-
-    private void dispatchPrepareFromSearch(RemoteUserInfo caller, String query, Bundle extras) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_SEARCH, query, extras);
-    }
-
-    private void dispatchPrepareFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_URI, uri, extras);
-    }
-
-    private void dispatchPlay(RemoteUserInfo caller) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PLAY, null, null);
-    }
-
-    private void dispatchPlayFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PLAY_MEDIA_ID, mediaId, extras);
-    }
-
-    private void dispatchPlayFromSearch(RemoteUserInfo caller, String query, Bundle extras) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PLAY_SEARCH, query, extras);
-    }
-
-    private void dispatchPlayFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PLAY_URI, uri, extras);
-    }
-
-    private void dispatchSkipToItem(RemoteUserInfo caller, long id) {
-        postToCallback(caller, CallbackMessageHandler.MSG_SKIP_TO_ITEM, id, null);
-    }
-
-    private void dispatchPause(RemoteUserInfo caller) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PAUSE, null, null);
-    }
-
-    private void dispatchStop(RemoteUserInfo caller) {
-        postToCallback(caller, CallbackMessageHandler.MSG_STOP, null, null);
-    }
-
-    private void dispatchNext(RemoteUserInfo caller) {
-        postToCallback(caller, CallbackMessageHandler.MSG_NEXT, null, null);
-    }
-
-    private void dispatchPrevious(RemoteUserInfo caller) {
-        postToCallback(caller, CallbackMessageHandler.MSG_PREVIOUS, null, null);
-    }
-
-    private void dispatchFastForward(RemoteUserInfo caller) {
-        postToCallback(caller, CallbackMessageHandler.MSG_FAST_FORWARD, null, null);
-    }
-
-    private void dispatchRewind(RemoteUserInfo caller) {
-        postToCallback(caller, CallbackMessageHandler.MSG_REWIND, null, null);
-    }
-
-    private void dispatchSeekTo(RemoteUserInfo caller, long pos) {
-        postToCallback(caller, CallbackMessageHandler.MSG_SEEK_TO, pos, null);
-    }
-
-    private void dispatchRate(RemoteUserInfo caller, Rating rating) {
-        postToCallback(caller, CallbackMessageHandler.MSG_RATE, rating, null);
-    }
-
-    private void dispatchCustomAction(RemoteUserInfo caller, String action, Bundle args) {
-        postToCallback(caller, CallbackMessageHandler.MSG_CUSTOM_ACTION, action, args);
-    }
-
-    private void dispatchMediaButton(RemoteUserInfo caller, Intent mediaButtonIntent) {
-        postToCallback(caller, CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent, null);
-    }
-
-    private void dispatchMediaButtonDelayed(RemoteUserInfo info, Intent mediaButtonIntent,
-            long delay) {
-        postToCallbackDelayed(info, CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT,
-                mediaButtonIntent, null, delay);
-    }
-
-    private void dispatchAdjustVolume(RemoteUserInfo caller, int direction) {
-        postToCallback(caller, CallbackMessageHandler.MSG_ADJUST_VOLUME, direction, null);
-    }
-
-    private void dispatchSetVolumeTo(RemoteUserInfo caller, int volume) {
-        postToCallback(caller, CallbackMessageHandler.MSG_SET_VOLUME, volume, null);
-    }
-
-    private void dispatchCommand(RemoteUserInfo caller, String command, Bundle args,
-            ResultReceiver resultCb) {
-        Command cmd = new Command(command, args, resultCb);
-        postToCallback(caller, CallbackMessageHandler.MSG_COMMAND, cmd, null);
-    }
-
-    private void postToCallback(RemoteUserInfo caller, int what, Object obj, Bundle data) {
-        postToCallbackDelayed(caller, what, obj, data, 0);
-    }
-
-    private void postToCallbackDelayed(RemoteUserInfo caller, int what, Object obj, Bundle data,
-            long delay) {
-        synchronized (mLock) {
-            if (mCallback != null) {
-                mCallback.post(caller, what, obj, data, delay);
-            }
-        }
+        return mImpl.getCallingPackage();
     }
 
     /**
@@ -672,17 +417,7 @@
      * @hide
      */
     public static boolean isActiveState(int state) {
-        switch (state) {
-            case PlaybackState.STATE_FAST_FORWARDING:
-            case PlaybackState.STATE_REWINDING:
-            case PlaybackState.STATE_SKIPPING_TO_PREVIOUS:
-            case PlaybackState.STATE_SKIPPING_TO_NEXT:
-            case PlaybackState.STATE_BUFFERING:
-            case PlaybackState.STATE_CONNECTING:
-            case PlaybackState.STATE_PLAYING:
-                return true;
-        }
-        return false;
+        return MediaSessionEngine.isActiveState(state);
     }
 
     /**
@@ -692,13 +427,13 @@
      */
     public static final class Token implements Parcelable {
 
-        private ControllerLink mBinder;
+        private ControllerLink mControllerLink;
 
         /**
          * @hide
          */
-        public Token(ControllerLink binder) {
-            mBinder = binder;
+        public Token(ControllerLink controllerLink) {
+            mControllerLink = controllerLink;
         }
 
         @Override
@@ -708,14 +443,15 @@
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
-            dest.writeParcelable(mBinder, flags);
+            dest.writeParcelable(mControllerLink, flags);
         }
 
         @Override
         public int hashCode() {
             final int prime = 31;
             int result = 1;
-            result = prime * result + ((mBinder == null) ? 0 : mBinder.getBinder().hashCode());
+            result = prime * result + ((mControllerLink == null)
+                    ? 0 : mControllerLink.getBinder().hashCode());
             return result;
         }
 
@@ -728,17 +464,23 @@
             if (getClass() != obj.getClass())
                 return false;
             Token other = (Token) obj;
-            if (mBinder == null) {
-                if (other.mBinder != null)
+            if (mControllerLink == null) {
+                if (other.mControllerLink != null) {
                     return false;
-            } else if (!mBinder.getBinder().equals(other.mBinder.getBinder())) {
+                }
+            } else if (!mControllerLink.getBinder().equals(other.mControllerLink.getBinder())) {
                 return false;
             }
             return true;
         }
 
-        ControllerLink getBinder() {
-            return mBinder;
+        /**
+         * Gets the controller link in this token.
+         * @hide
+         */
+        @SystemApi
+        ControllerLink getControllerLink() {
+            return mControllerLink;
         }
 
         public static final Parcelable.Creator<Token> CREATOR =
@@ -762,9 +504,7 @@
      */
     public abstract static class Callback {
 
-        private MediaSession mSession;
-        private CallbackMessageHandler mHandler;
-        private boolean mMediaPlayPauseKeyPending;
+        MediaSessionEngine.MediaButtonEventDelegate mMediaButtonEventDelegate;
 
         public Callback() {
         }
@@ -796,110 +536,12 @@
          * @return True if the event was handled, false otherwise.
          */
         public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) {
-            if (mSession != null && mHandler != null
-                    && Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) {
-                KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
-                if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) {
-                    PlaybackState state = mSession.mPlaybackState;
-                    long validActions = state == null ? 0 : state.getActions();
-                    switch (ke.getKeyCode()) {
-                        case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
-                        case KeyEvent.KEYCODE_HEADSETHOOK:
-                            if (ke.getRepeatCount() > 0) {
-                                // Consider long-press as a single tap.
-                                handleMediaPlayPauseKeySingleTapIfPending();
-                            } else if (mMediaPlayPauseKeyPending) {
-                                // Consider double tap as the next.
-                                mHandler.removeMessages(CallbackMessageHandler
-                                        .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT);
-                                mMediaPlayPauseKeyPending = false;
-                                if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) {
-                                    onSkipToNext();
-                                }
-                            } else {
-                                mMediaPlayPauseKeyPending = true;
-                                mSession.dispatchMediaButtonDelayed(
-                                        mSession.getCurrentControllerInfo(),
-                                        mediaButtonIntent, ViewConfiguration.getDoubleTapTimeout());
-                            }
-                            return true;
-                        default:
-                            // If another key is pressed within double tap timeout, consider the
-                            // pending play/pause as a single tap to handle media keys in order.
-                            handleMediaPlayPauseKeySingleTapIfPending();
-                            break;
-                    }
-
-                    switch (ke.getKeyCode()) {
-                        case KeyEvent.KEYCODE_MEDIA_PLAY:
-                            if ((validActions & PlaybackState.ACTION_PLAY) != 0) {
-                                onPlay();
-                                return true;
-                            }
-                            break;
-                        case KeyEvent.KEYCODE_MEDIA_PAUSE:
-                            if ((validActions & PlaybackState.ACTION_PAUSE) != 0) {
-                                onPause();
-                                return true;
-                            }
-                            break;
-                        case KeyEvent.KEYCODE_MEDIA_NEXT:
-                            if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) {
-                                onSkipToNext();
-                                return true;
-                            }
-                            break;
-                        case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
-                            if ((validActions & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0) {
-                                onSkipToPrevious();
-                                return true;
-                            }
-                            break;
-                        case KeyEvent.KEYCODE_MEDIA_STOP:
-                            if ((validActions & PlaybackState.ACTION_STOP) != 0) {
-                                onStop();
-                                return true;
-                            }
-                            break;
-                        case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
-                            if ((validActions & PlaybackState.ACTION_FAST_FORWARD) != 0) {
-                                onFastForward();
-                                return true;
-                            }
-                            break;
-                        case KeyEvent.KEYCODE_MEDIA_REWIND:
-                            if ((validActions & PlaybackState.ACTION_REWIND) != 0) {
-                                onRewind();
-                                return true;
-                            }
-                            break;
-                    }
-                }
+            if (mMediaButtonEventDelegate != null) {
+                return mMediaButtonEventDelegate.onMediaButtonIntent(mediaButtonIntent);
             }
             return false;
         }
 
-        private void handleMediaPlayPauseKeySingleTapIfPending() {
-            if (!mMediaPlayPauseKeyPending) {
-                return;
-            }
-            mMediaPlayPauseKeyPending = false;
-            mHandler.removeMessages(CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT);
-            PlaybackState state = mSession.mPlaybackState;
-            long validActions = state == null ? 0 : state.getActions();
-            boolean isPlaying = state != null
-                    && state.getState() == PlaybackState.STATE_PLAYING;
-            boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
-                        | PlaybackState.ACTION_PLAY)) != 0;
-            boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
-                        | PlaybackState.ACTION_PAUSE)) != 0;
-            if (isPlaying && canPause) {
-                onPause();
-            } else if (!isPlaying && canPlay) {
-                onPlay();
-            }
-        }
-
         /**
          * Override to handle requests to prepare playback. During the preparation, a session should
          * not hold audio focus in order to allow other sessions play seamlessly. The state of
@@ -1042,251 +684,14 @@
          */
         public void onCustomAction(@NonNull String action, @Nullable Bundle extras) {
         }
-    }
 
-    /**
-     * @hide
-     */
-    public static final class CallbackStub extends SessionCallbackLink.CallbackStub {
-        private WeakReference<MediaSession> mMediaSession;
-
-        public CallbackStub(MediaSession session) {
-            mMediaSession = new WeakReference<>(session);
-        }
-
-        private static RemoteUserInfo createRemoteUserInfo(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
-            return new RemoteUserInfo(packageName, pid, uid,
-                    caller != null ? caller.getBinder() : null);
-        }
-
-        @Override
-        public void onCommand(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchCommand(createRemoteUserInfo(packageName, pid, uid, caller),
-                        command, args, cb);
-            }
-        }
-
-        @Override
-        public void onMediaButton(String packageName, int pid, int uid, Intent mediaButtonIntent,
-                int sequenceNumber, ResultReceiver cb) {
-            MediaSession session = mMediaSession.get();
-            try {
-                if (session != null) {
-                    session.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid, null),
-                            mediaButtonIntent);
-                }
-            } finally {
-                if (cb != null) {
-                    cb.send(sequenceNumber, null);
-                }
-            }
-        }
-
-        @Override
-        public void onMediaButtonFromController(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, Intent mediaButtonIntent) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid, caller),
-                        mediaButtonIntent);
-            }
-        }
-
-        @Override
-        public void onPrepare(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPrepare(createRemoteUserInfo(packageName, pid, uid, caller));
-            }
-        }
-
-        @Override
-        public void onPrepareFromMediaId(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String mediaId,
-                Bundle extras) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPrepareFromMediaId(
-                        createRemoteUserInfo(packageName, pid, uid, caller), mediaId, extras);
-            }
-        }
-
-        @Override
-        public void onPrepareFromSearch(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String query,
-                Bundle extras) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPrepareFromSearch(
-                        createRemoteUserInfo(packageName, pid, uid, caller), query, extras);
-            }
-        }
-
-        @Override
-        public void onPrepareFromUri(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, Uri uri, Bundle extras) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPrepareFromUri(createRemoteUserInfo(packageName, pid, uid, caller),
-                        uri, extras);
-            }
-        }
-
-        @Override
-        public void onPlay(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPlay(createRemoteUserInfo(packageName, pid, uid, caller));
-            }
-        }
-
-        @Override
-        public void onPlayFromMediaId(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String mediaId,
-                Bundle extras) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPlayFromMediaId(createRemoteUserInfo(packageName, pid, uid, caller),
-                        mediaId, extras);
-            }
-        }
-
-        @Override
-        public void onPlayFromSearch(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String query,
-                Bundle extras) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPlayFromSearch(createRemoteUserInfo(packageName, pid, uid, caller),
-                        query, extras);
-            }
-        }
-
-        @Override
-        public void onPlayFromUri(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, Uri uri, Bundle extras) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPlayFromUri(createRemoteUserInfo(packageName, pid, uid, caller),
-                        uri, extras);
-            }
-        }
-
-        @Override
-        public void onSkipToTrack(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, long id) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchSkipToItem(createRemoteUserInfo(packageName, pid, uid, caller), id);
-            }
-        }
-
-        @Override
-        public void onPause(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPause(createRemoteUserInfo(packageName, pid, uid, caller));
-            }
-        }
-
-        @Override
-        public void onStop(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchStop(createRemoteUserInfo(packageName, pid, uid, caller));
-            }
-        }
-
-        @Override
-        public void onNext(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchNext(createRemoteUserInfo(packageName, pid, uid, caller));
-            }
-        }
-
-        @Override
-        public void onPrevious(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchPrevious(createRemoteUserInfo(packageName, pid, uid, caller));
-            }
-        }
-
-        @Override
-        public void onFastForward(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchFastForward(createRemoteUserInfo(packageName, pid, uid, caller));
-            }
-        }
-
-        @Override
-        public void onRewind(String packageName, int pid, int uid,
-                ControllerCallbackLink caller) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchRewind(createRemoteUserInfo(packageName, pid, uid, caller));
-            }
-        }
-
-        @Override
-        public void onSeekTo(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, long pos) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchSeekTo(createRemoteUserInfo(packageName, pid, uid, caller), pos);
-            }
-        }
-
-        @Override
-        public void onRate(String packageName, int pid, int uid, ControllerCallbackLink caller,
-                Rating rating) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchRate(createRemoteUserInfo(packageName, pid, uid, caller), rating);
-            }
-        }
-
-        @Override
-        public void onCustomAction(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, String action, Bundle args) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchCustomAction(createRemoteUserInfo(packageName, pid, uid, caller),
-                        action, args);
-            }
-        }
-
-        @Override
-        public void onAdjustVolume(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, int direction) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchAdjustVolume(createRemoteUserInfo(packageName, pid, uid, caller),
-                        direction);
-            }
-        }
-
-        @Override
-        public void onSetVolumeTo(String packageName, int pid, int uid,
-                ControllerCallbackLink caller, int value) {
-            MediaSession session = mMediaSession.get();
-            if (session != null) {
-                session.dispatchSetVolumeTo(createRemoteUserInfo(packageName, pid, uid, caller),
-                        value);
-            }
+        /**
+         * @hide
+         */
+        @SystemApi
+        public void onSetMediaButtonEventDelegate(
+                @NonNull MediaSessionEngine.MediaButtonEventDelegate delegate) {
+            mMediaButtonEventDelegate = delegate;
         }
     }
 
@@ -1300,7 +705,7 @@
          */
         public static final int UNKNOWN_ID = -1;
 
-        private final MediaDescription mDescription;
+        private final MediaSessionEngine.QueueItem mImpl;
         @UnsupportedAppUsage
         private final long mId;
 
@@ -1312,18 +717,12 @@
          *            play queue and cannot be {@link #UNKNOWN_ID}.
          */
         public QueueItem(MediaDescription description, long id) {
-            if (description == null) {
-                throw new IllegalArgumentException("Description cannot be null.");
-            }
-            if (id == UNKNOWN_ID) {
-                throw new IllegalArgumentException("Id cannot be QueueItem.UNKNOWN_ID");
-            }
-            mDescription = description;
+            mImpl = new MediaSessionEngine.QueueItem(description, id);
             mId = id;
         }
 
         private QueueItem(Parcel in) {
-            mDescription = MediaDescription.CREATOR.createFromParcel(in);
+            mImpl = new MediaSessionEngine.QueueItem(in);
             mId = in.readLong();
         }
 
@@ -1331,20 +730,19 @@
          * Get the description for this item.
          */
         public MediaDescription getDescription() {
-            return mDescription;
+            return mImpl.getDescription();
         }
 
         /**
          * Get the queue id for this item.
          */
         public long getQueueId() {
-            return mId;
+            return mImpl.getQueueId();
         }
 
         @Override
         public void writeToParcel(Parcel dest, int flags) {
-            mDescription.writeToParcel(dest, flags);
-            dest.writeLong(mId);
+            mImpl.writeToParcel(dest, flags);
         }
 
         @Override
@@ -1368,9 +766,7 @@
 
         @Override
         public String toString() {
-            return "MediaSession.QueueItem {" +
-                    "Description=" + mDescription +
-                    ", Id=" + mId + " }";
+            return mImpl.toString();
         }
 
         @Override
@@ -1383,167 +779,7 @@
                 return false;
             }
 
-            final QueueItem item = (QueueItem) o;
-            if (mId != item.mId) {
-                return false;
-            }
-
-            if (!Objects.equals(mDescription, item.mDescription)) {
-                return false;
-            }
-
-            return true;
-        }
-    }
-
-    private static final class Command {
-        public final String command;
-        public final Bundle extras;
-        public final ResultReceiver stub;
-
-        public Command(String command, Bundle extras, ResultReceiver stub) {
-            this.command = command;
-            this.extras = extras;
-            this.stub = stub;
-        }
-    }
-
-    private class CallbackMessageHandler extends Handler {
-        private static final int MSG_COMMAND = 1;
-        private static final int MSG_MEDIA_BUTTON = 2;
-        private static final int MSG_PREPARE = 3;
-        private static final int MSG_PREPARE_MEDIA_ID = 4;
-        private static final int MSG_PREPARE_SEARCH = 5;
-        private static final int MSG_PREPARE_URI = 6;
-        private static final int MSG_PLAY = 7;
-        private static final int MSG_PLAY_MEDIA_ID = 8;
-        private static final int MSG_PLAY_SEARCH = 9;
-        private static final int MSG_PLAY_URI = 10;
-        private static final int MSG_SKIP_TO_ITEM = 11;
-        private static final int MSG_PAUSE = 12;
-        private static final int MSG_STOP = 13;
-        private static final int MSG_NEXT = 14;
-        private static final int MSG_PREVIOUS = 15;
-        private static final int MSG_FAST_FORWARD = 16;
-        private static final int MSG_REWIND = 17;
-        private static final int MSG_SEEK_TO = 18;
-        private static final int MSG_RATE = 19;
-        private static final int MSG_CUSTOM_ACTION = 20;
-        private static final int MSG_ADJUST_VOLUME = 21;
-        private static final int MSG_SET_VOLUME = 22;
-        private static final int MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT = 23;
-
-        private MediaSession.Callback mCallback;
-        private RemoteUserInfo mCurrentControllerInfo;
-
-        public CallbackMessageHandler(Looper looper, MediaSession.Callback callback) {
-            super(looper);
-            mCallback = callback;
-            mCallback.mHandler = this;
-        }
-
-        public void post(RemoteUserInfo caller, int what, Object obj, Bundle data, long delayMs) {
-            Pair<RemoteUserInfo, Object> objWithCaller = Pair.create(caller, obj);
-            Message msg = obtainMessage(what, objWithCaller);
-            msg.setAsynchronous(true);
-            msg.setData(data);
-            if (delayMs > 0) {
-                sendMessageDelayed(msg, delayMs);
-            } else {
-                sendMessage(msg);
-            }
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            mCurrentControllerInfo = ((Pair<RemoteUserInfo, Object>) msg.obj).first;
-
-            VolumeProvider vp;
-            Object obj = ((Pair<RemoteUserInfo, Object>) msg.obj).second;
-
-            switch (msg.what) {
-                case MSG_COMMAND:
-                    Command cmd = (Command) obj;
-                    mCallback.onCommand(cmd.command, cmd.extras, cmd.stub);
-                    break;
-                case MSG_MEDIA_BUTTON:
-                    mCallback.onMediaButtonEvent((Intent) obj);
-                    break;
-                case MSG_PREPARE:
-                    mCallback.onPrepare();
-                    break;
-                case MSG_PREPARE_MEDIA_ID:
-                    mCallback.onPrepareFromMediaId((String) obj, msg.getData());
-                    break;
-                case MSG_PREPARE_SEARCH:
-                    mCallback.onPrepareFromSearch((String) obj, msg.getData());
-                    break;
-                case MSG_PREPARE_URI:
-                    mCallback.onPrepareFromUri((Uri) obj, msg.getData());
-                    break;
-                case MSG_PLAY:
-                    mCallback.onPlay();
-                    break;
-                case MSG_PLAY_MEDIA_ID:
-                    mCallback.onPlayFromMediaId((String) obj, msg.getData());
-                    break;
-                case MSG_PLAY_SEARCH:
-                    mCallback.onPlayFromSearch((String) obj, msg.getData());
-                    break;
-                case MSG_PLAY_URI:
-                    mCallback.onPlayFromUri((Uri) obj, msg.getData());
-                    break;
-                case MSG_SKIP_TO_ITEM:
-                    mCallback.onSkipToQueueItem((Long) obj);
-                    break;
-                case MSG_PAUSE:
-                    mCallback.onPause();
-                    break;
-                case MSG_STOP:
-                    mCallback.onStop();
-                    break;
-                case MSG_NEXT:
-                    mCallback.onSkipToNext();
-                    break;
-                case MSG_PREVIOUS:
-                    mCallback.onSkipToPrevious();
-                    break;
-                case MSG_FAST_FORWARD:
-                    mCallback.onFastForward();
-                    break;
-                case MSG_REWIND:
-                    mCallback.onRewind();
-                    break;
-                case MSG_SEEK_TO:
-                    mCallback.onSeekTo((Long) obj);
-                    break;
-                case MSG_RATE:
-                    mCallback.onSetRating((Rating) obj);
-                    break;
-                case MSG_CUSTOM_ACTION:
-                    mCallback.onCustomAction((String) obj, msg.getData());
-                    break;
-                case MSG_ADJUST_VOLUME:
-                    synchronized (mLock) {
-                        vp = mVolumeProvider;
-                    }
-                    if (vp != null) {
-                        vp.onAdjustVolume((int) obj);
-                    }
-                    break;
-                case MSG_SET_VOLUME:
-                    synchronized (mLock) {
-                        vp = mVolumeProvider;
-                    }
-                    if (vp != null) {
-                        vp.onSetVolumeTo((int) obj);
-                    }
-                    break;
-                case MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT:
-                    mCallback.handleMediaPlayPauseKeySingleTapIfPending();
-                    break;
-            }
-            mCurrentControllerInfo = null;
+            return mImpl.equals(((QueueItem) o).mImpl);
         }
     }
 }
diff --git a/media/java/android/media/session/MediaSessionEngine.java b/media/java/android/media/session/MediaSessionEngine.java
new file mode 100644
index 0000000..c4634a9
--- /dev/null
+++ b/media/java/android/media/session/MediaSessionEngine.java
@@ -0,0 +1,1481 @@
+/*
+ * Copyright 2019 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.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+import android.annotation.UnsupportedAppUsage;
+import android.app.Activity;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
+import android.media.AudioAttributes;
+import android.media.MediaDescription;
+import android.media.MediaMetadata;
+import android.media.Rating;
+import android.media.VolumeProvider;
+import android.media.session.MediaSessionManager.RemoteUserInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.ResultReceiver;
+import android.service.media.MediaBrowserService;
+import android.text.TextUtils;
+import android.util.Log;
+import android.util.Pair;
+import android.view.KeyEvent;
+import android.view.ViewConfiguration;
+
+import java.lang.ref.WeakReference;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * @hide
+ */
+@SystemApi
+public final class MediaSessionEngine implements AutoCloseable {
+    private static final String TAG = MediaSession.TAG;
+
+    private final Object mLock = new Object();
+    private final int mMaxBitmapSize;
+
+    private final MediaSession.Token mSessionToken;
+    private final MediaController mController;
+    private final SessionLink mSessionLink;
+    private final SessionCallbackLink mCbLink;
+
+    // Do not change the name of mCallbackWrapper. Support lib accesses this by using reflection.
+    @UnsupportedAppUsage
+    private CallbackMessageHandler mCallbackHandler;
+    private VolumeProvider mVolumeProvider;
+    private PlaybackState mPlaybackState;
+
+    private boolean mActive = false;
+
+    /**
+     * Creates a new session. The session will automatically be registered with
+     * the system but will not be published until {@link #setActive(boolean)
+     * setActive(true)} is called. You must call {@link #close()} when
+     * finished with the session.
+     *
+     * @param context The context to use to create the session.
+     * @param sessionLink A session link for the binder of MediaSessionRecord
+     * @param cbStub A callback link that handles incoming command to {@link MediaSession.Callback}.
+     */
+    public MediaSessionEngine(@NonNull Context context, @NonNull SessionLink sessionLink,
+            @NonNull SessionCallbackLink cbLink, @NonNull CallbackStub cbStub, int maxBitmapSize) {
+        mSessionLink = sessionLink;
+        mCbLink = cbLink;
+        mMaxBitmapSize = maxBitmapSize;
+
+        cbStub.setSessionImpl(this);
+        mSessionToken = new MediaSession.Token(mSessionLink.getController());
+        mController = new MediaController(context, mSessionToken);
+    }
+
+    /**
+     * Set the callback to receive updates for the MediaSession. This includes
+     * media button events and transport controls. The caller's thread will be
+     * used to post updates.
+     * <p>
+     * Set the callback to null to stop receiving updates.
+     *
+     * @param callback The callback object
+     */
+    public void setCallback(@Nullable MediaSession.Callback callback) {
+        setCallback(callback, new Handler());
+    }
+
+    /**
+     * Set the callback to receive updates for the MediaSession. This includes
+     * media button events and transport controls.
+     * <p>
+     * Set the callback to null to stop receiving updates.
+     *
+     * @param callback The callback to receive updates on.
+     * @param handler The handler that events should be posted on.
+     */
+    public void setCallback(@Nullable MediaSession.Callback callback, @NonNull Handler handler) {
+        setCallbackInternal(callback == null ? null : new CallbackWrapper(callback), handler);
+    }
+
+    private void setCallbackInternal(CallbackWrapper callback, Handler handler) {
+        synchronized (mLock) {
+            if (mCallbackHandler != null) {
+                // We're updating the callback, clear the session from the old one.
+                mCallbackHandler.mCallbackWrapper.mSessionImpl = null;
+                mCallbackHandler.removeCallbacksAndMessages(null);
+            }
+            if (callback == null) {
+                mCallbackHandler = null;
+                return;
+            }
+            callback.mSessionImpl = this;
+            CallbackMessageHandler msgHandler = new CallbackMessageHandler(handler.getLooper(),
+                    callback);
+            mCallbackHandler = msgHandler;
+        }
+    }
+
+    /**
+     * Set an intent for launching UI for this Session. This can be used as a
+     * quick link to an ongoing media screen. The intent should be for an
+     * activity that may be started using {@link Activity#startActivity(Intent)}.
+     *
+     * @param pi The intent to launch to show UI for this Session.
+     */
+    public void setSessionActivity(@Nullable PendingIntent pi) {
+        try {
+            mSessionLink.setLaunchPendingIntent(pi);
+        } catch (RuntimeException e) {
+            Log.wtf(TAG, "Failure in setLaunchPendingIntent.", e);
+        }
+    }
+
+    /**
+     * Set a pending intent for your media button receiver to allow restarting
+     * playback after the session has been stopped. If your app is started in
+     * this way an {@link Intent#ACTION_MEDIA_BUTTON} intent will be sent via
+     * the pending intent.
+     *
+     * @param mbr The {@link PendingIntent} to send the media button event to.
+     */
+    public void setMediaButtonReceiver(@Nullable PendingIntent mbr) {
+        try {
+            mSessionLink.setMediaButtonReceiver(mbr);
+        } catch (RuntimeException e) {
+            Log.wtf(TAG, "Failure in setMediaButtonReceiver.", e);
+        }
+    }
+
+    /**
+     * Set any flags for the session.
+     *
+     * @param flags The flags to set for this session.
+     */
+    public void setFlags(@MediaSession.SessionFlags int flags) {
+        try {
+            mSessionLink.setFlags(flags);
+        } catch (RuntimeException e) {
+            Log.wtf(TAG, "Failure in setFlags.", e);
+        }
+    }
+
+    /**
+     * Set the attributes for this session's audio. This will affect the
+     * system's volume handling for this session. If
+     * {@link #setPlaybackToRemote} was previously called it will stop receiving
+     * volume commands and the system will begin sending volume changes to the
+     * appropriate stream.
+     * <p>
+     * By default sessions use attributes for media.
+     *
+     * @param attributes The {@link AudioAttributes} for this session's audio.
+     */
+    public void setPlaybackToLocal(AudioAttributes attributes) {
+        if (attributes == null) {
+            throw new IllegalArgumentException("Attributes cannot be null for local playback.");
+        }
+        try {
+            mSessionLink.setPlaybackToLocal(attributes);
+        } catch (RuntimeException e) {
+            Log.wtf(TAG, "Failure in setPlaybackToLocal.", e);
+        }
+    }
+
+    /**
+     * Configure this session to use remote volume handling. This must be called
+     * to receive volume button events, otherwise the system will adjust the
+     * appropriate stream volume for this session. If
+     * {@link #setPlaybackToLocal} was previously called the system will stop
+     * handling volume changes for this session and pass them to the volume
+     * provider instead.
+     *
+     * @param volumeProvider The provider that will handle volume changes. May
+     *            not be null.
+     */
+    public void setPlaybackToRemote(@NonNull VolumeProvider volumeProvider) {
+        if (volumeProvider == null) {
+            throw new IllegalArgumentException("volumeProvider may not be null!");
+        }
+        synchronized (mLock) {
+            mVolumeProvider = volumeProvider;
+        }
+        volumeProvider.setCallback(new VolumeProvider.Callback() {
+            @Override
+            public void onVolumeChanged(VolumeProvider volumeProvider) {
+                notifyRemoteVolumeChanged(volumeProvider);
+            }
+        });
+
+        try {
+            mSessionLink.setPlaybackToRemote(volumeProvider.getVolumeControl(),
+                    volumeProvider.getMaxVolume());
+            mSessionLink.setCurrentVolume(volumeProvider.getCurrentVolume());
+        } catch (RuntimeException e) {
+            Log.wtf(TAG, "Failure in setPlaybackToRemote.", e);
+        }
+    }
+
+    /**
+     * Set if this session is currently active and ready to receive commands. If
+     * set to false your session's controller may not be discoverable. You must
+     * set the session to active before it can start receiving media button
+     * events or transport commands.
+     *
+     * @param active Whether this session is active or not.
+     */
+    public void setActive(boolean active) {
+        if (mActive == active) {
+            return;
+        }
+        try {
+            mSessionLink.setActive(active);
+            mActive = active;
+        } catch (RuntimeException e) {
+            Log.wtf(TAG, "Failure in setActive.", e);
+        }
+    }
+
+    /**
+     * Get the current active state of this session.
+     *
+     * @return True if the session is active, false otherwise.
+     */
+    public boolean isActive() {
+        return mActive;
+    }
+
+    /**
+     * Send a proprietary event to all MediaControllers listening to this
+     * Session. It's up to the Controller/Session owner to determine the meaning
+     * of any events.
+     *
+     * @param event The name of the event to send
+     * @param extras Any extras included with the event
+     */
+    public void sendSessionEvent(@NonNull String event, @Nullable Bundle extras) {
+        if (TextUtils.isEmpty(event)) {
+            throw new IllegalArgumentException("event cannot be null or empty");
+        }
+        try {
+            mSessionLink.sendEvent(event, extras);
+        } catch (RuntimeException e) {
+            Log.wtf(TAG, "Error sending event", e);
+        }
+    }
+
+    /**
+     * This must be called when an app has finished performing playback. If
+     * playback is expected to start again shortly the session can be left open,
+     * but it must be released if your activity or service is being destroyed.
+     */
+    public void close() {
+        try {
+            mSessionLink.destroySession();
+        } catch (RuntimeException e) {
+            Log.wtf(TAG, "Error releasing session: ", e);
+        }
+    }
+
+    /**
+     * Retrieve a token object that can be used by apps to create a
+     * {@link MediaController} for interacting with this session. The owner of
+     * the session is responsible for deciding how to distribute these tokens.
+     *
+     * @return A token that can be used to create a MediaController for this
+     *         session
+     */
+    public @NonNull MediaSession.Token getSessionToken() {
+        return mSessionToken;
+    }
+
+    /**
+     * Get a controller for this session. This is a convenience method to avoid
+     * having to cache your own controller in process.
+     *
+     * @return A controller for this session.
+     */
+    public @NonNull MediaController getController() {
+        return mController;
+    }
+
+    /**
+     * Update the current playback state.
+     *
+     * @param state The current state of playback
+     */
+    public void setPlaybackState(@Nullable PlaybackState state) {
+        mPlaybackState = state;
+        try {
+            mSessionLink.setPlaybackState(state);
+        } catch (RuntimeException e) {
+            Log.wtf(TAG, "Dead object in setPlaybackState.", e);
+        }
+    }
+
+    /**
+     * Update the current metadata. New metadata can be created using
+     * {@link android.media.MediaMetadata.Builder}. This operation may take time proportional to
+     * the size of the bitmap to replace large bitmaps with a scaled down copy.
+     *
+     * @param metadata The new metadata
+     * @see android.media.MediaMetadata.Builder#putBitmap
+     */
+    public void setMetadata(@Nullable MediaMetadata metadata) {
+        long duration = -1;
+        int fields = 0;
+        MediaDescription description = null;
+        if (metadata != null) {
+            metadata = (new MediaMetadata.Builder(metadata, mMaxBitmapSize)).build();
+            if (metadata.containsKey(MediaMetadata.METADATA_KEY_DURATION)) {
+                duration = metadata.getLong(MediaMetadata.METADATA_KEY_DURATION);
+            }
+            fields = metadata.size();
+            description = metadata.getDescription();
+        }
+        String metadataDescription = "size=" + fields + ", description=" + description;
+
+        try {
+            mSessionLink.setMetadata(metadata, duration, metadataDescription);
+        } catch (RuntimeException e) {
+            Log.wtf(TAG, "Dead object in setPlaybackState.", e);
+        }
+    }
+
+    /**
+     * Update the list of items in the play queue. It is an ordered list and
+     * should contain the current item, and previous or upcoming items if they
+     * exist. Specify null if there is no current play queue.
+     * <p>
+     * The queue should be of reasonable size. If the play queue is unbounded
+     * within your app, it is better to send a reasonable amount in a sliding
+     * window instead.
+     *
+     * @param queue A list of items in the play queue.
+     */
+    public void setQueue(@Nullable List<MediaSession.QueueItem> queue) {
+        try {
+            mSessionLink.setQueue(queue);
+        } catch (RuntimeException e) {
+            Log.wtf("Dead object in setQueue.", e);
+        }
+    }
+
+    /**
+     * Set the title of the play queue. The UI should display this title along
+     * with the play queue itself.
+     * e.g. "Play Queue", "Now Playing", or an album name.
+     *
+     * @param title The title of the play queue.
+     */
+    public void setQueueTitle(@Nullable CharSequence title) {
+        try {
+            mSessionLink.setQueueTitle(title);
+        } catch (RuntimeException e) {
+            Log.wtf("Dead object in setQueueTitle.", e);
+        }
+    }
+
+    /**
+     * Set the style of rating used by this session. Apps trying to set the
+     * rating should use this style. Must be one of the following:
+     * <ul>
+     * <li>{@link Rating#RATING_NONE}</li>
+     * <li>{@link Rating#RATING_3_STARS}</li>
+     * <li>{@link Rating#RATING_4_STARS}</li>
+     * <li>{@link Rating#RATING_5_STARS}</li>
+     * <li>{@link Rating#RATING_HEART}</li>
+     * <li>{@link Rating#RATING_PERCENTAGE}</li>
+     * <li>{@link Rating#RATING_THUMB_UP_DOWN}</li>
+     * </ul>
+     */
+    public void setRatingType(@Rating.Style int type) {
+        try {
+            mSessionLink.setRatingType(type);
+        } catch (RuntimeException e) {
+            Log.e(TAG, "Error in setRatingType.", e);
+        }
+    }
+
+    /**
+     * Set some extras that can be associated with the {@link MediaSession}. No assumptions should
+     * be made as to how a {@link MediaController} will handle these extras.
+     * Keys should be fully qualified (e.g. com.example.MY_EXTRA) to avoid conflicts.
+     *
+     * @param extras The extras associated with the {@link MediaSession}.
+     */
+    public void setExtras(@Nullable Bundle extras) {
+        try {
+            mSessionLink.setExtras(extras);
+        } catch (RuntimeException e) {
+            Log.wtf("Dead object in setExtras.", e);
+        }
+    }
+
+    /**
+     * Gets the controller information who sent the current request.
+     * <p>
+     * Note: This is only valid while in a request callback, such as
+     * {@link MediaSession.Callback#onPlay}.
+     *
+     * @throws IllegalStateException If this method is called outside of
+     * {@link MediaSession.Callback} methods.
+     * @see MediaSessionManager#isTrustedForMediaControl(RemoteUserInfo)
+     */
+    public @NonNull RemoteUserInfo getCurrentControllerInfo() {
+        if (mCallbackHandler == null || mCallbackHandler.mCurrentControllerInfo == null) {
+            throw new IllegalStateException(
+                    "This should be called inside of MediaSession.Callback methods");
+        }
+        return mCallbackHandler.mCurrentControllerInfo;
+    }
+
+    /**
+     * Notify the system that the remote volume changed.
+     *
+     * @param provider The provider that is handling volume changes.
+     * @hide
+     */
+    public void notifyRemoteVolumeChanged(VolumeProvider provider) {
+        synchronized (mLock) {
+            if (provider == null || provider != mVolumeProvider) {
+                Log.w(TAG, "Received update from stale volume provider");
+                return;
+            }
+        }
+        try {
+            mSessionLink.setCurrentVolume(provider.getCurrentVolume());
+        } catch (RuntimeException e) {
+            Log.e(TAG, "Error in notifyVolumeChanged", e);
+        }
+    }
+
+    /**
+     * Returns the name of the package that sent the last media button, transport control, or
+     * command from controllers and the system. This is only valid while in a request callback, such
+     * as {@link MediaSession.Callback#onPlay}.
+     */
+    public String getCallingPackage() {
+        if (mCallbackHandler != null && mCallbackHandler.mCurrentControllerInfo != null) {
+            return mCallbackHandler.mCurrentControllerInfo.getPackageName();
+        }
+        return null;
+    }
+
+    private void dispatchPrepare(RemoteUserInfo caller) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PREPARE, null, null);
+    }
+
+    private void dispatchPrepareFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_MEDIA_ID, mediaId, extras);
+    }
+
+    private void dispatchPrepareFromSearch(RemoteUserInfo caller, String query, Bundle extras) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_SEARCH, query, extras);
+    }
+
+    private void dispatchPrepareFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PREPARE_URI, uri, extras);
+    }
+
+    private void dispatchPlay(RemoteUserInfo caller) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PLAY, null, null);
+    }
+
+    private void dispatchPlayFromMediaId(RemoteUserInfo caller, String mediaId, Bundle extras) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PLAY_MEDIA_ID, mediaId, extras);
+    }
+
+    private void dispatchPlayFromSearch(RemoteUserInfo caller, String query, Bundle extras) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PLAY_SEARCH, query, extras);
+    }
+
+    private void dispatchPlayFromUri(RemoteUserInfo caller, Uri uri, Bundle extras) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PLAY_URI, uri, extras);
+    }
+
+    private void dispatchSkipToItem(RemoteUserInfo caller, long id) {
+        postToCallback(caller, CallbackMessageHandler.MSG_SKIP_TO_ITEM, id, null);
+    }
+
+    private void dispatchPause(RemoteUserInfo caller) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PAUSE, null, null);
+    }
+
+    private void dispatchStop(RemoteUserInfo caller) {
+        postToCallback(caller, CallbackMessageHandler.MSG_STOP, null, null);
+    }
+
+    private void dispatchNext(RemoteUserInfo caller) {
+        postToCallback(caller, CallbackMessageHandler.MSG_NEXT, null, null);
+    }
+
+    private void dispatchPrevious(RemoteUserInfo caller) {
+        postToCallback(caller, CallbackMessageHandler.MSG_PREVIOUS, null, null);
+    }
+
+    private void dispatchFastForward(RemoteUserInfo caller) {
+        postToCallback(caller, CallbackMessageHandler.MSG_FAST_FORWARD, null, null);
+    }
+
+    private void dispatchRewind(RemoteUserInfo caller) {
+        postToCallback(caller, CallbackMessageHandler.MSG_REWIND, null, null);
+    }
+
+    private void dispatchSeekTo(RemoteUserInfo caller, long pos) {
+        postToCallback(caller, CallbackMessageHandler.MSG_SEEK_TO, pos, null);
+    }
+
+    private void dispatchRate(RemoteUserInfo caller, Rating rating) {
+        postToCallback(caller, CallbackMessageHandler.MSG_RATE, rating, null);
+    }
+
+    private void dispatchCustomAction(RemoteUserInfo caller, String action, Bundle args) {
+        postToCallback(caller, CallbackMessageHandler.MSG_CUSTOM_ACTION, action, args);
+    }
+
+    private void dispatchMediaButton(RemoteUserInfo caller, Intent mediaButtonIntent) {
+        postToCallback(caller, CallbackMessageHandler.MSG_MEDIA_BUTTON, mediaButtonIntent, null);
+    }
+
+    private void dispatchMediaButtonDelayed(RemoteUserInfo info, Intent mediaButtonIntent,
+            long delay) {
+        postToCallbackDelayed(info, CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT,
+                mediaButtonIntent, null, delay);
+    }
+
+    private void dispatchAdjustVolume(RemoteUserInfo caller, int direction) {
+        postToCallback(caller, CallbackMessageHandler.MSG_ADJUST_VOLUME, direction, null);
+    }
+
+    private void dispatchSetVolumeTo(RemoteUserInfo caller, int volume) {
+        postToCallback(caller, CallbackMessageHandler.MSG_SET_VOLUME, volume, null);
+    }
+
+    private void dispatchCommand(RemoteUserInfo caller, String command, Bundle args,
+            ResultReceiver resultCb) {
+        Command cmd = new Command(command, args, resultCb);
+        postToCallback(caller, CallbackMessageHandler.MSG_COMMAND, cmd, null);
+    }
+
+    private void postToCallback(RemoteUserInfo caller, int what, Object obj, Bundle data) {
+        postToCallbackDelayed(caller, what, obj, data, 0);
+    }
+
+    private void postToCallbackDelayed(RemoteUserInfo caller, int what, Object obj, Bundle data,
+            long delay) {
+        synchronized (mLock) {
+            if (mCallbackHandler != null) {
+                mCallbackHandler.post(caller, what, obj, data, delay);
+            }
+        }
+    }
+
+    /**
+     * Return true if this is considered an active playback state.
+     */
+    public static boolean isActiveState(int state) {
+        switch (state) {
+            case PlaybackState.STATE_FAST_FORWARDING:
+            case PlaybackState.STATE_REWINDING:
+            case PlaybackState.STATE_SKIPPING_TO_PREVIOUS:
+            case PlaybackState.STATE_SKIPPING_TO_NEXT:
+            case PlaybackState.STATE_BUFFERING:
+            case PlaybackState.STATE_CONNECTING:
+            case PlaybackState.STATE_PLAYING:
+                return true;
+        }
+        return false;
+    }
+
+    /**
+     * Interface for handling MediaButtoneEvent
+     */
+    public interface MediaButtonEventDelegate {
+        /**
+         * Called when a media button is pressed and this session has the
+         * highest priority or a controller sends a media button event to the
+         * session.
+         *
+         * @param mediaButtonIntent an intent containing the KeyEvent as an extra
+         * @return True if the event was handled, false otherwise.
+         */
+        boolean onMediaButtonIntent(Intent mediaButtonIntent);
+    }
+
+    /**
+     * Receives media buttons, transport controls, and commands from controllers
+     * and the system. A callback may be set using {@link #setCallback}.
+     * @hide
+     */
+    public static class CallbackWrapper implements MediaButtonEventDelegate {
+
+        private final MediaSession.Callback mCallback;
+
+        @SuppressWarnings("WeakerAccess") /* synthetic access */
+                MediaSessionEngine mSessionImpl;
+        @SuppressWarnings("WeakerAccess") /* synthetic access */
+        CallbackMessageHandler mHandler;
+        private boolean mMediaPlayPauseKeyPending;
+
+        public CallbackWrapper(MediaSession.Callback callback) {
+            mCallback = callback;
+            if (mCallback != null) {
+                mCallback.onSetMediaButtonEventDelegate(this);
+            }
+        }
+
+        /**
+         * Called when a controller has sent a command to this session.
+         * The owner of the session may handle custom commands but is not
+         * required to.
+         *
+         * @param command The command name.
+         * @param args Optional parameters for the command, may be null.
+         * @param cb A result receiver to which a result may be sent by the command, may be null.
+         */
+        public void onCommand(@NonNull String command, @Nullable Bundle args,
+                @Nullable ResultReceiver cb) {
+            if (mCallback != null) {
+                mCallback.onCommand(command, args, cb);
+            }
+        }
+
+        /**
+         * Called when a media button is pressed and this session has the
+         * highest priority or a controller sends a media button event to the
+         * session. The default behavior will call the relevant method if the
+         * action for it was set.
+         * <p>
+         * The intent will be of type {@link Intent#ACTION_MEDIA_BUTTON} with a
+         * KeyEvent in {@link Intent#EXTRA_KEY_EVENT}
+         *
+         * @param mediaButtonIntent an intent containing the KeyEvent as an
+         *            extra
+         * @return True if the event was handled, false otherwise.
+         */
+        public boolean onMediaButtonEvent(@NonNull Intent mediaButtonIntent) {
+            return mCallback == null ? false : mCallback.onMediaButtonEvent(mediaButtonIntent);
+        }
+
+        private void handleMediaPlayPauseKeySingleTapIfPending() {
+            if (!mMediaPlayPauseKeyPending) {
+                return;
+            }
+            mMediaPlayPauseKeyPending = false;
+            mHandler.removeMessages(CallbackMessageHandler.MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT);
+            PlaybackState state = mSessionImpl.mPlaybackState;
+            long validActions = state == null ? 0 : state.getActions();
+            boolean isPlaying = state != null
+                    && state.getState() == PlaybackState.STATE_PLAYING;
+            boolean canPlay = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
+                    | PlaybackState.ACTION_PLAY)) != 0;
+            boolean canPause = (validActions & (PlaybackState.ACTION_PLAY_PAUSE
+                    | PlaybackState.ACTION_PAUSE)) != 0;
+            if (isPlaying && canPause) {
+                onPause();
+            } else if (!isPlaying && canPlay) {
+                onPlay();
+            }
+        }
+
+        /**
+         * Override to handle requests to prepare playback. During the preparation, a session should
+         * not hold audio focus in order to allow other sessions play seamlessly. The state of
+         * playback should be updated to {@link PlaybackState#STATE_PAUSED} after the preparation is
+         * done.
+         */
+        public void onPrepare() {
+            if (mCallback != null) {
+                mCallback.onPrepare();
+            }
+        }
+
+        /**
+         * Override to handle requests to prepare for playing a specific mediaId that was provided
+         * by your app's {@link MediaBrowserService}. During the preparation, a session should not
+         * hold audio focus in order to allow other sessions play seamlessly. The state of playback
+         * should be updated to {@link PlaybackState#STATE_PAUSED} after the preparation is done.
+         * The playback of the prepared content should start in the implementation of
+         * {@link #onPlay}. Override {@link #onPlayFromMediaId} to handle requests for starting
+         * playback without preparation.
+         */
+        public void onPrepareFromMediaId(String mediaId, Bundle extras) {
+            if (mCallback != null) {
+                mCallback.onPrepareFromMediaId(mediaId, extras);
+            }
+        }
+
+        /**
+         * Override to handle requests to prepare playback from a search query. An empty query
+         * indicates that the app may prepare any music. The implementation should attempt to make a
+         * smart choice about what to play. During the preparation, a session should not hold audio
+         * focus in order to allow other sessions play seamlessly. The state of playback should be
+         * updated to {@link PlaybackState#STATE_PAUSED} after the preparation is done. The playback
+         * of the prepared content should start in the implementation of {@link #onPlay}. Override
+         * {@link #onPlayFromSearch} to handle requests for starting playback without preparation.
+         */
+        public void onPrepareFromSearch(String query, Bundle extras) {
+            if (mCallback != null) {
+                mCallback.onPrepareFromSearch(query, extras);
+            }
+        }
+
+        /**
+         * Override to handle requests to prepare a specific media item represented by a URI.
+         * During the preparation, a session should not hold audio focus in order to allow
+         * other sessions play seamlessly. The state of playback should be updated to
+         * {@link PlaybackState#STATE_PAUSED} after the preparation is done.
+         * The playback of the prepared content should start in the implementation of
+         * {@link #onPlay}. Override {@link #onPlayFromUri} to handle requests
+         * for starting playback without preparation.
+         */
+        public void onPrepareFromUri(Uri uri, Bundle extras) {
+            if (mCallback != null) {
+                mCallback.onPrepareFromUri(uri, extras);
+            }
+        }
+
+        /**
+         * Override to handle requests to begin playback.
+         */
+        public void onPlay() {
+            if (mCallback != null) {
+                mCallback.onPlay();
+            }
+        }
+
+        /**
+         * Override to handle requests to begin playback from a search query. An
+         * empty query indicates that the app may play any music. The
+         * implementation should attempt to make a smart choice about what to
+         * play.
+         */
+        public void onPlayFromSearch(String query, Bundle extras) {
+            if (mCallback != null) {
+                mCallback.onPlayFromSearch(query, extras);
+            }
+        }
+
+        /**
+         * Override to handle requests to play a specific mediaId that was
+         * provided by your app's {@link MediaBrowserService}.
+         */
+        public void onPlayFromMediaId(String mediaId, Bundle extras) {
+            if (mCallback != null) {
+                mCallback.onPlayFromMediaId(mediaId, extras);
+            }
+        }
+
+        /**
+         * Override to handle requests to play a specific media item represented by a URI.
+         */
+        public void onPlayFromUri(Uri uri, Bundle extras) {
+            if (mCallback != null) {
+                mCallback.onPlayFromUri(uri, extras);
+            }
+        }
+
+        /**
+         * Override to handle requests to play an item with a given id from the
+         * play queue.
+         */
+        public void onSkipToQueueItem(long id) {
+            if (mCallback != null) {
+                mCallback.onSkipToQueueItem(id);
+            }
+        }
+
+        /**
+         * Override to handle requests to pause playback.
+         */
+        public void onPause() {
+            if (mCallback != null) {
+                mCallback.onPause();
+            }
+        }
+
+        /**
+         * Override to handle requests to skip to the next media item.
+         */
+        public void onSkipToNext() {
+            if (mCallback != null) {
+                mCallback.onSkipToNext();
+            }
+        }
+
+        /**
+         * Override to handle requests to skip to the previous media item.
+         */
+        public void onSkipToPrevious() {
+            if (mCallback != null) {
+                mCallback.onSkipToPrevious();
+            }
+        }
+
+        /**
+         * Override to handle requests to fast forward.
+         */
+        public void onFastForward() {
+            if (mCallback != null) {
+                mCallback.onFastForward();
+            }
+        }
+
+        /**
+         * Override to handle requests to rewind.
+         */
+        public void onRewind() {
+            if (mCallback != null) {
+                mCallback.onRewind();
+            }
+        }
+
+        /**
+         * Override to handle requests to stop playback.
+         */
+        public void onStop() {
+            if (mCallback != null) {
+                mCallback.onStop();
+            }
+        }
+
+        /**
+         * Override to handle requests to seek to a specific position in ms.
+         *
+         * @param pos New position to move to, in milliseconds.
+         */
+        public void onSeekTo(long pos) {
+            if (mCallback != null) {
+                mCallback.onSeekTo(pos);
+            }
+        }
+
+        /**
+         * Override to handle the item being rated.
+         *
+         * @param rating
+         */
+        public void onSetRating(@NonNull Rating rating) {
+            if (mCallback != null) {
+                mCallback.onSetRating(rating);
+            }
+        }
+
+        /**
+         * Called when a {@link MediaController} wants a {@link PlaybackState.CustomAction} to be
+         * performed.
+         *
+         * @param action The action that was originally sent in the
+         *               {@link PlaybackState.CustomAction}.
+         * @param extras Optional extras specified by the {@link MediaController}.
+         */
+        public void onCustomAction(@NonNull String action, @Nullable Bundle extras) {
+            if (mCallback != null) {
+                mCallback.onCustomAction(action, extras);
+            }
+        }
+
+        @Override
+        public boolean onMediaButtonIntent(Intent mediaButtonIntent) {
+            if (mSessionImpl != null && mHandler != null
+                    && Intent.ACTION_MEDIA_BUTTON.equals(mediaButtonIntent.getAction())) {
+                KeyEvent ke = mediaButtonIntent.getParcelableExtra(Intent.EXTRA_KEY_EVENT);
+                if (ke != null && ke.getAction() == KeyEvent.ACTION_DOWN) {
+                    PlaybackState state = mSessionImpl.mPlaybackState;
+                    long validActions = state == null ? 0 : state.getActions();
+                    switch (ke.getKeyCode()) {
+                        case KeyEvent.KEYCODE_MEDIA_PLAY_PAUSE:
+                        case KeyEvent.KEYCODE_HEADSETHOOK:
+                            if (ke.getRepeatCount() > 0) {
+                                // Consider long-press as a single tap.
+                                handleMediaPlayPauseKeySingleTapIfPending();
+                            } else if (mMediaPlayPauseKeyPending) {
+                                // Consider double tap as the next.
+                                mHandler.removeMessages(CallbackMessageHandler
+                                        .MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT);
+                                mMediaPlayPauseKeyPending = false;
+                                if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) {
+                                    onSkipToNext();
+                                }
+                            } else {
+                                mMediaPlayPauseKeyPending = true;
+                                mSessionImpl.dispatchMediaButtonDelayed(
+                                        mSessionImpl.getCurrentControllerInfo(),
+                                        mediaButtonIntent, ViewConfiguration.getDoubleTapTimeout());
+                            }
+                            return true;
+                        default:
+                            // If another key is pressed within double tap timeout, consider the
+                            // pending play/pause as a single tap to handle media keys in order.
+                            handleMediaPlayPauseKeySingleTapIfPending();
+                            break;
+                    }
+
+                    switch (ke.getKeyCode()) {
+                        case KeyEvent.KEYCODE_MEDIA_PLAY:
+                            if ((validActions & PlaybackState.ACTION_PLAY) != 0) {
+                                onPlay();
+                                return true;
+                            }
+                            break;
+                        case KeyEvent.KEYCODE_MEDIA_PAUSE:
+                            if ((validActions & PlaybackState.ACTION_PAUSE) != 0) {
+                                onPause();
+                                return true;
+                            }
+                            break;
+                        case KeyEvent.KEYCODE_MEDIA_NEXT:
+                            if ((validActions & PlaybackState.ACTION_SKIP_TO_NEXT) != 0) {
+                                onSkipToNext();
+                                return true;
+                            }
+                            break;
+                        case KeyEvent.KEYCODE_MEDIA_PREVIOUS:
+                            if ((validActions & PlaybackState.ACTION_SKIP_TO_PREVIOUS) != 0) {
+                                onSkipToPrevious();
+                                return true;
+                            }
+                            break;
+                        case KeyEvent.KEYCODE_MEDIA_STOP:
+                            if ((validActions & PlaybackState.ACTION_STOP) != 0) {
+                                onStop();
+                                return true;
+                            }
+                            break;
+                        case KeyEvent.KEYCODE_MEDIA_FAST_FORWARD:
+                            if ((validActions & PlaybackState.ACTION_FAST_FORWARD) != 0) {
+                                onFastForward();
+                                return true;
+                            }
+                            break;
+                        case KeyEvent.KEYCODE_MEDIA_REWIND:
+                            if ((validActions & PlaybackState.ACTION_REWIND) != 0) {
+                                onRewind();
+                                return true;
+                            }
+                            break;
+                    }
+                }
+            }
+            return false;
+        }
+    }
+
+    /**
+     * @hide
+     */
+    @SystemApi
+    public static final class CallbackStub extends SessionCallbackLink.CallbackStub {
+        private WeakReference<MediaSessionEngine> mSessionImpl;
+
+        private static RemoteUserInfo createRemoteUserInfo(String packageName, int pid, int uid,
+                ControllerCallbackLink caller) {
+            return new RemoteUserInfo(packageName, pid, uid,
+                    caller != null ? caller.getBinder() : null);
+        }
+
+        public CallbackStub() {
+        }
+
+        @Override
+        public void onCommand(String packageName, int pid, int uid,
+                ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchCommand(createRemoteUserInfo(packageName, pid, uid, caller),
+                        command, args, cb);
+            }
+        }
+
+        @Override
+        public void onMediaButton(String packageName, int pid, int uid, Intent mediaButtonIntent,
+                int sequenceNumber, ResultReceiver cb) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            try {
+                if (sessionImpl != null) {
+                    sessionImpl.dispatchMediaButton(
+                            createRemoteUserInfo(packageName, pid, uid, null), mediaButtonIntent);
+                }
+            } finally {
+                if (cb != null) {
+                    cb.send(sequenceNumber, null);
+                }
+            }
+        }
+
+        @Override
+        public void onMediaButtonFromController(String packageName, int pid, int uid,
+                ControllerCallbackLink caller, Intent mediaButtonIntent) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchMediaButton(createRemoteUserInfo(packageName, pid, uid, caller),
+                        mediaButtonIntent);
+            }
+        }
+
+        @Override
+        public void onPrepare(String packageName, int pid, int uid,
+                ControllerCallbackLink caller) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchPrepare(createRemoteUserInfo(packageName, pid, uid, caller));
+            }
+        }
+
+        @Override
+        public void onPrepareFromMediaId(String packageName, int pid, int uid,
+                ControllerCallbackLink caller, String mediaId,
+                Bundle extras) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchPrepareFromMediaId(
+                        createRemoteUserInfo(packageName, pid, uid, caller), mediaId, extras);
+            }
+        }
+
+        @Override
+        public void onPrepareFromSearch(String packageName, int pid, int uid,
+                ControllerCallbackLink caller, String query,
+                Bundle extras) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchPrepareFromSearch(
+                        createRemoteUserInfo(packageName, pid, uid, caller), query, extras);
+            }
+        }
+
+        @Override
+        public void onPrepareFromUri(String packageName, int pid, int uid,
+                ControllerCallbackLink caller, Uri uri, Bundle extras) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchPrepareFromUri(
+                        createRemoteUserInfo(packageName, pid, uid, caller), uri, extras);
+            }
+        }
+
+        @Override
+        public void onPlay(String packageName, int pid, int uid,
+                ControllerCallbackLink caller) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchPlay(createRemoteUserInfo(packageName, pid, uid, caller));
+            }
+        }
+
+        @Override
+        public void onPlayFromMediaId(String packageName, int pid, int uid,
+                ControllerCallbackLink caller, String mediaId,
+                Bundle extras) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchPlayFromMediaId(
+                        createRemoteUserInfo(packageName, pid, uid, caller), mediaId, extras);
+            }
+        }
+
+        @Override
+        public void onPlayFromSearch(String packageName, int pid, int uid,
+                ControllerCallbackLink caller, String query,
+                Bundle extras) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchPlayFromSearch(
+                        createRemoteUserInfo(packageName, pid, uid, caller), query, extras);
+            }
+        }
+
+        @Override
+        public void onPlayFromUri(String packageName, int pid, int uid,
+                ControllerCallbackLink caller, Uri uri, Bundle extras) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchPlayFromUri(
+                        createRemoteUserInfo(packageName, pid, uid, caller), uri, extras);
+            }
+        }
+
+        @Override
+        public void onSkipToTrack(String packageName, int pid, int uid,
+                ControllerCallbackLink caller, long id) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchSkipToItem(
+                        createRemoteUserInfo(packageName, pid, uid, caller), id);
+            }
+        }
+
+        @Override
+        public void onPause(String packageName, int pid, int uid,
+                ControllerCallbackLink caller) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchPause(createRemoteUserInfo(packageName, pid, uid, caller));
+            }
+        }
+
+        @Override
+        public void onStop(String packageName, int pid, int uid,
+                ControllerCallbackLink caller) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchStop(createRemoteUserInfo(packageName, pid, uid, caller));
+            }
+        }
+
+        @Override
+        public void onNext(String packageName, int pid, int uid,
+                ControllerCallbackLink caller) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchNext(createRemoteUserInfo(packageName, pid, uid, caller));
+            }
+        }
+
+        @Override
+        public void onPrevious(String packageName, int pid, int uid,
+                ControllerCallbackLink caller) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchPrevious(createRemoteUserInfo(packageName, pid, uid, caller));
+            }
+        }
+
+        @Override
+        public void onFastForward(String packageName, int pid, int uid,
+                ControllerCallbackLink caller) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchFastForward(
+                        createRemoteUserInfo(packageName, pid, uid, caller));
+            }
+        }
+
+        @Override
+        public void onRewind(String packageName, int pid, int uid,
+                ControllerCallbackLink caller) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchRewind(createRemoteUserInfo(packageName, pid, uid, caller));
+            }
+        }
+
+        @Override
+        public void onSeekTo(String packageName, int pid, int uid,
+                ControllerCallbackLink caller, long pos) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchSeekTo(
+                        createRemoteUserInfo(packageName, pid, uid, caller), pos);
+            }
+        }
+
+        @Override
+        public void onRate(String packageName, int pid, int uid, ControllerCallbackLink caller,
+                Rating rating) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchRate(
+                        createRemoteUserInfo(packageName, pid, uid, caller), rating);
+            }
+        }
+
+        @Override
+        public void onCustomAction(String packageName, int pid, int uid,
+                ControllerCallbackLink caller, String action, Bundle args) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchCustomAction(
+                        createRemoteUserInfo(packageName, pid, uid, caller), action, args);
+            }
+        }
+
+        @Override
+        public void onAdjustVolume(String packageName, int pid, int uid,
+                ControllerCallbackLink caller, int direction) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchAdjustVolume(
+                        createRemoteUserInfo(packageName, pid, uid, caller), direction);
+            }
+        }
+
+        @Override
+        public void onSetVolumeTo(String packageName, int pid, int uid,
+                ControllerCallbackLink caller, int value) {
+            MediaSessionEngine sessionImpl = mSessionImpl.get();
+            if (sessionImpl != null) {
+                sessionImpl.dispatchSetVolumeTo(
+                        createRemoteUserInfo(packageName, pid, uid, caller), value);
+            }
+        }
+
+        void setSessionImpl(MediaSessionEngine sessionImpl) {
+            mSessionImpl = new WeakReference<>(sessionImpl);
+        }
+    }
+
+    /**
+     * A single item that is part of the play queue. It contains a description
+     * of the item and its id in the queue.
+     */
+    public static final class QueueItem {
+        /**
+         * This id is reserved. No items can be explicitly assigned this id.
+         */
+        public static final int UNKNOWN_ID = -1;
+
+        private final MediaDescription mDescription;
+        private final long mId;
+
+        /**
+         * Create a new {@link MediaSession.QueueItem}.
+         *
+         * @param description The {@link MediaDescription} for this item.
+         * @param id An identifier for this item. It must be unique within the
+         *            play queue and cannot be {@link #UNKNOWN_ID}.
+         */
+        public QueueItem(MediaDescription description, long id) {
+            if (description == null) {
+                throw new IllegalArgumentException("Description cannot be null.");
+            }
+            if (id == UNKNOWN_ID) {
+                throw new IllegalArgumentException("Id cannot be QueueItem.UNKNOWN_ID");
+            }
+            mDescription = description;
+            mId = id;
+        }
+
+        public QueueItem(Parcel in) {
+            mDescription = MediaDescription.CREATOR.createFromParcel(in);
+            mId = in.readLong();
+        }
+
+        /**
+         * Get the description for this item.
+         */
+        public MediaDescription getDescription() {
+            return mDescription;
+        }
+
+        /**
+         * Get the queue id for this item.
+         */
+        public long getQueueId() {
+            return mId;
+        }
+
+        /**
+         * Flatten this object in to a Parcel.
+         *
+         * @param dest The Parcel in which the object should be written.
+         * @param flags Additional flags about how the object should be written.
+         */
+        public void writeToParcel(Parcel dest, int flags) {
+            mDescription.writeToParcel(dest, flags);
+            dest.writeLong(mId);
+        }
+
+        @Override
+        public String toString() {
+            return "MediaSession.QueueItem {" + "Description=" + mDescription + ", Id=" + mId
+                    + " }";
+        }
+
+        @Override
+        public boolean equals(Object o) {
+            if (o == null) {
+                return false;
+            }
+
+            if (!(o instanceof QueueItem)) {
+                return false;
+            }
+
+            final QueueItem item = (QueueItem) o;
+            if (mId != item.mId) {
+                return false;
+            }
+
+            if (!Objects.equals(mDescription, item.mDescription)) {
+                return false;
+            }
+
+            return true;
+        }
+    }
+
+    private static final class Command {
+        public final String command;
+        public final Bundle extras;
+        public final ResultReceiver stub;
+
+        Command(String command, Bundle extras, ResultReceiver stub) {
+            this.command = command;
+            this.extras = extras;
+            this.stub = stub;
+        }
+    }
+
+    private class CallbackMessageHandler extends Handler {
+        private static final int MSG_COMMAND = 1;
+        private static final int MSG_MEDIA_BUTTON = 2;
+        private static final int MSG_PREPARE = 3;
+        private static final int MSG_PREPARE_MEDIA_ID = 4;
+        private static final int MSG_PREPARE_SEARCH = 5;
+        private static final int MSG_PREPARE_URI = 6;
+        private static final int MSG_PLAY = 7;
+        private static final int MSG_PLAY_MEDIA_ID = 8;
+        private static final int MSG_PLAY_SEARCH = 9;
+        private static final int MSG_PLAY_URI = 10;
+        private static final int MSG_SKIP_TO_ITEM = 11;
+        private static final int MSG_PAUSE = 12;
+        private static final int MSG_STOP = 13;
+        private static final int MSG_NEXT = 14;
+        private static final int MSG_PREVIOUS = 15;
+        private static final int MSG_FAST_FORWARD = 16;
+        private static final int MSG_REWIND = 17;
+        private static final int MSG_SEEK_TO = 18;
+        private static final int MSG_RATE = 19;
+        private static final int MSG_CUSTOM_ACTION = 20;
+        private static final int MSG_ADJUST_VOLUME = 21;
+        private static final int MSG_SET_VOLUME = 22;
+        private static final int MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT = 23;
+
+        @SuppressWarnings("WeakerAccess") /* synthetic access */
+        CallbackWrapper mCallbackWrapper;
+        @SuppressWarnings("WeakerAccess") /* synthetic access */
+        RemoteUserInfo mCurrentControllerInfo;
+
+        CallbackMessageHandler(Looper looper, CallbackWrapper callbackWrapper) {
+            super(looper);
+            mCallbackWrapper = callbackWrapper;
+            mCallbackWrapper.mHandler = this;
+        }
+
+        void post(RemoteUserInfo caller, int what, Object obj, Bundle data, long delayMs) {
+            Pair<RemoteUserInfo, Object> objWithCaller = Pair.create(caller, obj);
+            Message msg = obtainMessage(what, objWithCaller);
+            msg.setAsynchronous(true);
+            msg.setData(data);
+            if (delayMs > 0) {
+                sendMessageDelayed(msg, delayMs);
+            } else {
+                sendMessage(msg);
+            }
+        }
+
+        @Override
+        public void handleMessage(Message msg) {
+            mCurrentControllerInfo = ((Pair<RemoteUserInfo, Object>) msg.obj).first;
+
+            VolumeProvider vp;
+            Object obj = ((Pair<RemoteUserInfo, Object>) msg.obj).second;
+
+            switch (msg.what) {
+                case MSG_COMMAND:
+                    Command cmd = (Command) obj;
+                    mCallbackWrapper.onCommand(cmd.command, cmd.extras, cmd.stub);
+                    break;
+                case MSG_MEDIA_BUTTON:
+                    mCallbackWrapper.onMediaButtonEvent((Intent) obj);
+                    break;
+                case MSG_PREPARE:
+                    mCallbackWrapper.onPrepare();
+                    break;
+                case MSG_PREPARE_MEDIA_ID:
+                    mCallbackWrapper.onPrepareFromMediaId((String) obj, msg.getData());
+                    break;
+                case MSG_PREPARE_SEARCH:
+                    mCallbackWrapper.onPrepareFromSearch((String) obj, msg.getData());
+                    break;
+                case MSG_PREPARE_URI:
+                    mCallbackWrapper.onPrepareFromUri((Uri) obj, msg.getData());
+                    break;
+                case MSG_PLAY:
+                    mCallbackWrapper.onPlay();
+                    break;
+                case MSG_PLAY_MEDIA_ID:
+                    mCallbackWrapper.onPlayFromMediaId((String) obj, msg.getData());
+                    break;
+                case MSG_PLAY_SEARCH:
+                    mCallbackWrapper.onPlayFromSearch((String) obj, msg.getData());
+                    break;
+                case MSG_PLAY_URI:
+                    mCallbackWrapper.onPlayFromUri((Uri) obj, msg.getData());
+                    break;
+                case MSG_SKIP_TO_ITEM:
+                    mCallbackWrapper.onSkipToQueueItem((Long) obj);
+                    break;
+                case MSG_PAUSE:
+                    mCallbackWrapper.onPause();
+                    break;
+                case MSG_STOP:
+                    mCallbackWrapper.onStop();
+                    break;
+                case MSG_NEXT:
+                    mCallbackWrapper.onSkipToNext();
+                    break;
+                case MSG_PREVIOUS:
+                    mCallbackWrapper.onSkipToPrevious();
+                    break;
+                case MSG_FAST_FORWARD:
+                    mCallbackWrapper.onFastForward();
+                    break;
+                case MSG_REWIND:
+                    mCallbackWrapper.onRewind();
+                    break;
+                case MSG_SEEK_TO:
+                    mCallbackWrapper.onSeekTo((Long) obj);
+                    break;
+                case MSG_RATE:
+                    mCallbackWrapper.onSetRating((Rating) obj);
+                    break;
+                case MSG_CUSTOM_ACTION:
+                    mCallbackWrapper.onCustomAction((String) obj, msg.getData());
+                    break;
+                case MSG_ADJUST_VOLUME:
+                    synchronized (mLock) {
+                        vp = mVolumeProvider;
+                    }
+                    if (vp != null) {
+                        vp.onAdjustVolume((int) obj);
+                    }
+                    break;
+                case MSG_SET_VOLUME:
+                    synchronized (mLock) {
+                        vp = mVolumeProvider;
+                    }
+                    if (vp != null) {
+                        vp.onSetVolumeTo((int) obj);
+                    }
+                    break;
+                case MSG_PLAY_PAUSE_KEY_DOUBLE_TAP_TIMEOUT:
+                    mCallbackWrapper.handleMediaPlayPauseKeySingleTapIfPending();
+                    break;
+            }
+            mCurrentControllerInfo = null;
+        }
+    }
+}
diff --git a/media/java/android/media/session/SessionCallbackLink.java b/media/java/android/media/session/SessionCallbackLink.java
index 0265687b..0dbf427 100644
--- a/media/java/android/media/session/SessionCallbackLink.java
+++ b/media/java/android/media/session/SessionCallbackLink.java
@@ -669,7 +669,7 @@
         @Override
         public void notifyCommand(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, String command, Bundle args, ResultReceiver cb) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onCommand(packageName, pid, uid, caller, command, args, cb);
@@ -681,7 +681,7 @@
         @Override
         public void notifyMediaButton(String packageName, int pid, int uid,
                 Intent mediaButtonIntent, int sequenceNumber, ResultReceiver cb) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onMediaButton(packageName, pid, uid, mediaButtonIntent,
@@ -694,7 +694,7 @@
         @Override
         public void notifyMediaButtonFromController(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, Intent mediaButtonIntent) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onMediaButtonFromController(packageName, pid, uid, caller,
@@ -707,7 +707,7 @@
         @Override
         public void notifyPrepare(String packageName, int pid, int uid,
                 ControllerCallbackLink caller) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onPrepare(packageName, pid, uid, caller);
@@ -719,7 +719,7 @@
         @Override
         public void notifyPrepareFromMediaId(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, String mediaId, Bundle extras) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onPrepareFromMediaId(packageName, pid, uid, caller, mediaId, extras);
@@ -731,7 +731,7 @@
         @Override
         public void notifyPrepareFromSearch(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, String query, Bundle extras) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onPrepareFromSearch(packageName, pid, uid, caller, query, extras);
@@ -743,7 +743,7 @@
         @Override
         public void notifyPrepareFromUri(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, Uri uri, Bundle extras) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onPrepareFromUri(packageName, pid, uid, caller, uri, extras);
@@ -755,7 +755,7 @@
         @Override
         public void notifyPlay(String packageName, int pid, int uid,
                 ControllerCallbackLink caller) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onPlay(packageName, pid, uid, caller);
@@ -767,7 +767,7 @@
         @Override
         public void notifyPlayFromMediaId(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, String mediaId, Bundle extras) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onPlayFromMediaId(packageName, pid, uid, caller, mediaId, extras);
@@ -779,7 +779,7 @@
         @Override
         public void notifyPlayFromSearch(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, String query, Bundle extras) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onPlayFromSearch(packageName, pid, uid, caller, query, extras);
@@ -791,7 +791,7 @@
         @Override
         public void notifyPlayFromUri(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, Uri uri, Bundle extras) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onPlayFromUri(packageName, pid, uid, caller, uri, extras);
@@ -803,7 +803,7 @@
         @Override
         public void notifySkipToTrack(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, long id) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onSkipToTrack(packageName, pid, uid, caller, id);
@@ -815,7 +815,7 @@
         @Override
         public void notifyPause(String packageName, int pid, int uid,
                 ControllerCallbackLink caller) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onPause(packageName, pid, uid, caller);
@@ -827,7 +827,7 @@
         @Override
         public void notifyStop(String packageName, int pid, int uid,
                 ControllerCallbackLink caller) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onStop(packageName, pid, uid, caller);
@@ -839,7 +839,7 @@
         @Override
         public void notifyNext(String packageName, int pid, int uid,
                 ControllerCallbackLink caller) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onNext(packageName, pid, uid, caller);
@@ -851,7 +851,7 @@
         @Override
         public void notifyPrevious(String packageName, int pid, int uid,
                 ControllerCallbackLink caller) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onPrevious(packageName, pid, uid, caller);
@@ -863,7 +863,7 @@
         @Override
         public void notifyFastForward(String packageName, int pid, int uid,
                 ControllerCallbackLink caller) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onFastForward(packageName, pid, uid, caller);
@@ -875,7 +875,7 @@
         @Override
         public void notifyRewind(String packageName, int pid, int uid,
                 ControllerCallbackLink caller) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onRewind(packageName, pid, uid, caller);
@@ -887,7 +887,7 @@
         @Override
         public void notifySeekTo(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, long pos) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onSeekTo(packageName, pid, uid, caller, pos);
@@ -899,7 +899,7 @@
         @Override
         public void notifyRate(String packageName, int pid, int uid, ControllerCallbackLink caller,
                 Rating rating) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onRate(packageName, pid, uid, caller, rating);
@@ -910,7 +910,7 @@
 
         public void notifyCustomAction(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, String action, Bundle args) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onCustomAction(packageName, pid, uid, caller, action, args);
@@ -922,7 +922,7 @@
         @Override
         public void notifyAdjustVolume(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, int direction) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onAdjustVolume(packageName, pid, uid, caller, direction);
@@ -934,7 +934,7 @@
         @Override
         public void notifySetVolumeTo(String packageName, int pid, int uid,
                 ControllerCallbackLink caller, int value) {
-            ensureMediasControlPermission();
+            ensureMediaControlPermission();
             final long token = Binder.clearCallingIdentity();
             try {
                 mCallbackStub.onSetVolumeTo(packageName, pid, uid, caller, value);
@@ -943,7 +943,7 @@
             }
         }
 
-        private void ensureMediasControlPermission() {
+        private void ensureMediaControlPermission() {
             // Allow API calls from the System UI
             if (mContext.checkCallingPermission(android.Manifest.permission.STATUS_BAR_SERVICE)
                     == PackageManager.PERMISSION_GRANTED) {
