diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 7900c7f..2f2baa3 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -30,8 +30,8 @@
             android:name="android.car.application"
             android:resource="@xml/automotive_app_desc" />
 
-        <activity android:name=".MediaProxyActivity"
-            android:theme="@android:style/Theme.NoTitleBar"
+        <activity android:name=".MediaActivity"
+            android:theme="@style/CarDrawerActivityTheme"
             android:label="CarMediaApp"
             android:resizeableActivity="true"
             android:launchMode="singleTop">
diff --git a/src/com/android/car/media/MediaActivity.java b/src/com/android/car/media/MediaActivity.java
index ab282dc..3ff1d93 100644
--- a/src/com/android/car/media/MediaActivity.java
+++ b/src/com/android/car/media/MediaActivity.java
@@ -16,21 +16,23 @@
 package com.android.car.media;
 
 import android.content.ComponentName;
-import android.content.Context;
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.os.Bundle;
 import android.provider.MediaStore;
-import android.support.car.Car;
-import android.support.car.app.menu.CarDrawerActivity;
+import android.support.v4.app.Fragment;
 import android.util.Log;
 import android.util.Pair;
 import android.util.TypedValue;
 import android.view.View;
 
+import com.android.car.app.CarDrawerActivity;
+import com.android.car.app.CarDrawerAdapter;
+import com.android.car.media.drawer.MediaDrawerController;
+
 /**
  * This activity controls the UI of media. It also updates the connection status for the media app
- * by broadcast. Drawer menu is controlled by {@link MediaCarMenuCallbacks}.
+ * by broadcast. Drawer menu is controlled by {@link MediaDrawerController}.
  */
 public class MediaActivity extends CarDrawerActivity {
     private static final String ACTION_MEDIA_APP_STATE_CHANGE
@@ -59,21 +61,17 @@
      */
     private boolean mContentFragmentChangeQueued;
 
+    private MediaDrawerController mDrawerController;
     private View mScrimView;
     private CrossfadeImageView mAlbumArtView;
     private MediaPlaybackFragment mMediaPlaybackFragment;
-    private MediaCarMenuCallbacks mMediaCarMenuCallbacks;
-
-    public MediaActivity(Proxy proxy, Context context, Car car) {
-        super(proxy, context, car);
-    }
 
     @Override
     protected void onStart() {
         super.onStart();
         Intent i = new Intent(ACTION_MEDIA_APP_STATE_CHANGE);
         i.putExtra(EXTRA_MEDIA_APP_FOREGROUND, true);
-        getContext().sendBroadcast(i);
+        sendBroadcast(i);
 
         mIsStarted = true;
 
@@ -91,22 +89,21 @@
         super.onStop();
         Intent i = new Intent(ACTION_MEDIA_APP_STATE_CHANGE);
         i.putExtra(EXTRA_MEDIA_APP_FOREGROUND, false);
-        getContext().sendBroadcast(i);
+        sendBroadcast(i);
 
         mIsStarted = false;
     }
 
     @Override
     protected void onCreate(Bundle savedInstanceState) {
+        mDrawerController = new MediaDrawerController(this);
         super.onCreate(savedInstanceState);
-        setLightMode();
-        mMediaCarMenuCallbacks = new MediaCarMenuCallbacks(this);
-        setCarMenuCallbacks(mMediaCarMenuCallbacks);
-        setContentView(R.layout.media_activity);
+
+        setMainContent(R.layout.media_activity);
         mScrimView = findViewById(R.id.scrim);
         mAlbumArtView = (CrossfadeImageView) findViewById(R.id.album_art);
-        setBackgroundColor(getContext().getColor(R.color.music_default_artwork));
-        MediaManager.getInstance(getContext()).addListener(mListener);
+        setBackgroundColor(getColor(R.color.music_default_artwork));
+        MediaManager.getInstance(this).addListener(mListener);
     }
 
     @Override
@@ -114,10 +111,15 @@
         super.onDestroy();
         // Send the broadcast to let the current connected media app know it is disconnected now.
         sendMediaConnectionStatusBroadcast(
-                MediaManager.getInstance(getContext()).getCurrentComponent(),
+                MediaManager.getInstance(this).getCurrentComponent(),
                 MediaConstants.MEDIA_DISCONNECTED);
-        mMediaCarMenuCallbacks.cleanup();
-        MediaManager.getInstance(getContext()).removeListener(mListener);
+        mDrawerController.cleanup();
+        MediaManager.getInstance(this).removeListener(mListener);
+    }
+
+    @Override
+    protected CarDrawerAdapter getRootAdapter() {
+        return mDrawerController.getRootAdapter();
     }
 
     @Override
@@ -149,9 +151,7 @@
         }
 
         setIntent(intent);
-        if (isDrawerShowing()) {
-            closeDrawer();
-        }
+        closeDrawer();
     }
 
     @Override
@@ -230,19 +230,19 @@
                     intent.getStringExtra(MediaManager.KEY_MEDIA_PACKAGE),
                     intent.getStringExtra(MediaManager.KEY_MEDIA_CLASS)
             );
-            MediaManager.getInstance(getContext()).setMediaClientComponent(component);
+            MediaManager.getInstance(this).setMediaClientComponent(component);
         } else {
             if (Log.isLoggable(TAG, Log.DEBUG)) {
                 Log.d(TAG, "Launching most recent / default component.");
             }
 
             // Set it to the default GPM component.
-            MediaManager.getInstance(getContext()).connectToMostRecentMediaComponent(
-                    new CarClientServiceAdapter(getContext().getPackageManager()));
+            MediaManager.getInstance(this).connectToMostRecentMediaComponent(
+                    new CarClientServiceAdapter(getPackageManager()));
         }
 
         if (isSearchIntent(intent)) {
-            MediaManager.getInstance(getContext()).processSearchIntent(intent);
+            MediaManager.getInstance(this).processSearchIntent(intent);
             setIntent(null);
         }
     }
@@ -253,7 +253,7 @@
     }
 
     private void sendMediaConnectionStatusBroadcast(
-            ComponentName componentName, @Car.ConnectionType String connectionStatus) {
+            ComponentName componentName, String connectionStatus) {
         // It will be no current component if no media app is chosen before.
         if (componentName == null) {
             return;
@@ -262,10 +262,10 @@
         Intent intent = new Intent(MediaConstants.ACTION_MEDIA_STATUS);
         intent.setPackage(componentName.getPackageName());
         intent.putExtra(MediaConstants.MEDIA_CONNECTION_STATUS, connectionStatus);
-        getContext().sendBroadcast(intent);
+        sendBroadcast(intent);
     }
 
-    public void attachContentFragment() {
+    void attachContentFragment() {
         if (mMediaPlaybackFragment == null) {
             mMediaPlaybackFragment = new MediaPlaybackFragment();
         }
@@ -298,4 +298,15 @@
         @Override
         public void onStatusMessageChanged(String msg) {}
     };
-}
+
+    private void setContentFragment(Fragment fragment) {
+        getSupportFragmentManager().beginTransaction()
+                .replace(getContentContainerId(), fragment)
+                .commit();
+    }
+
+
+    void showQueueInDrawer() {
+        mDrawerController.showQueueInDrawer();
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/car/media/MediaCarMenuCallbacks.java b/src/com/android/car/media/MediaCarMenuCallbacks.java
deleted file mode 100644
index 26415ab..0000000
--- a/src/com/android/car/media/MediaCarMenuCallbacks.java
+++ /dev/null
@@ -1,618 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.car.media;
-
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.PorterDuff;
-import android.graphics.drawable.Drawable;
-import android.media.browse.MediaBrowser;
-import android.media.session.MediaController;
-import android.media.session.MediaSession;
-import android.media.session.PlaybackState;
-import android.os.Bundle;
-import android.os.Handler;
-import android.support.car.app.menu.CarMenu;
-import android.support.car.app.menu.CarMenuCallbacks;
-import android.support.car.app.menu.RootMenu;
-import android.support.car.app.menu.compat.CarMenuConstantsComapt;
-import android.text.TextUtils;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Manages all data needed for media drawer menu.
- */
-public class MediaCarMenuCallbacks extends CarMenuCallbacks {
-
-    public static final String QUEUE_ROOT = "QUEUE_ROOT";
-
-    private static final String TAG = "GH.MediaMenuCallbacks";
-    // MEDIA_APP_ROOT is used for onGetRoot() of MediaMenuCallbacks, which is called so early that
-    // MediaBrowser hasn't got the root already. So we return this default root first and store the
-    // real one in mRootId.
-    private static final String MEDIA_APP_ROOT = "MEDIA_APP_ROOT";
-    private static final String EXTRA_ICON_SIZE =
-            "com.google.android.gms.car.media.BrowserIconSize";
-    private static final String QUEUE_ITEM_PREFIX = "queue_item_prefix_";
-    private static final String MEDIA_QUEUE_EMPTY_PLACEHOLDER = "media_queue_emtpy_placeholder";
-
-    private final MediaActivity mActivity;
-    private final Context mContext;
-    private final Handler mHandler;
-    private MediaBrowser mBrowser;
-    private MediaController mController;
-    private CarMenu mMenuResult;
-    private String mMediaId;
-    private String mRootId;
-    // The media id we want to subscribe but media browser is not connected at that time.
-    private String mPendingMediaId;
-    private long mActiveQueueItemId;
-    private boolean mLoadQueueMenuPending;
-    // Whether we add "Queue" as the last item in the main menu.
-    private boolean mIsQueueInMenu;
-    private List<MediaBrowser.MediaItem> mItems;
-    private LoadQueueBitmapRunnable mLoadQueueBitmapRunnable;
-    private LoadMenuBitmapRunnable mLoadMenuBitmapRunnable;
-    // The parent ID is set whenever there's a onChildrenLoaded request.
-    private UpdateMenuRunnable mUpdateMenuRunnable = new UpdateMenuRunnable();
-
-    public MediaCarMenuCallbacks(MediaActivity activity) {
-        mActivity = activity;
-        mContext = activity.getContext();
-        mHandler = new Handler();
-        MediaManager.getInstance(mContext).addListener(mListener);
-    }
-
-    public void cleanup() {
-        MediaManager.getInstance(mContext).removeListener(mListener);
-        mHandler.removeCallbacksAndMessages(null);
-        if (mBrowser != null) {
-            if (mMediaId != null) {
-                mBrowser.unsubscribe(mMediaId);
-                mMediaId = null;
-            }
-            mBrowser.disconnect();
-            mBrowser = null;
-        }
-        if (mController != null) {
-            mController.unregisterCallback(mControllerCallback);
-            mController = null;
-        }
-    }
-
-    @Override
-    public RootMenu onGetRoot(Bundle hints) {
-        // Return the default fake root due to the real one maybe not ready at this time.
-        return new RootMenu(MEDIA_APP_ROOT);
-    }
-
-    @Override
-    public void onLoadChildren(String parentId, CarMenu result) {
-        Log.d(TAG, "onLoadChildren " + parentId);
-        resetCarMenu(result);
-        if (QUEUE_ROOT.equals(parentId)) {
-            // If mBrowser is not connected now, we will load the menu later when it is connected.
-            if (mBrowser == null || !mBrowser.isConnected()) {
-                if (Log.isLoggable(TAG, Log.DEBUG)) {
-                    Log.d(TAG, "MediaBrowser is not connected while loading menu.");
-                }
-                mLoadQueueMenuPending = true;
-                return;
-            }
-
-            // Unsubscribe the old id first, or else it will affect to subscribe the new one.
-            if (!TextUtils.isEmpty(mMediaId) && !QUEUE_ROOT.equals(mMediaId)) {
-                mBrowser.unsubscribe(mMediaId);
-            }
-            mMediaId = parentId;
-
-            loadQueueMenu();
-        } else {
-            // If mBrowser is not connected now, we will load the menu later when it is connected.
-            if (mBrowser == null || !mBrowser.isConnected()) {
-                if (Log.isLoggable(TAG, Log.DEBUG)) {
-                    Log.d(TAG, "MediaBrowser is not connected while loading menu.");
-                }
-                mPendingMediaId = parentId;
-                return;
-            }
-
-            // Unsubscribe the old id first, or else it will affect to subscribe the new one.
-            if (!TextUtils.isEmpty(mMediaId) && !QUEUE_ROOT.equals(mMediaId)) {
-                mBrowser.unsubscribe(mMediaId);
-            }
-            // Replace the fake root id with the real one, then we can use it to subscribe.
-            if (parentId.equals(MEDIA_APP_ROOT)) {
-                mMediaId = mRootId;
-            } else {
-                mMediaId = parentId;
-            }
-            mBrowser.subscribe(mMediaId, mSubscriptionCallback);
-        }
-    }
-
-    @Override
-    public void onItemClicked(String id) {
-        // We treat queue item specially because its id is different from the normal one.
-        if (id.startsWith(QUEUE_ITEM_PREFIX)) {
-            String index = id.substring(QUEUE_ITEM_PREFIX.length());
-            mController.getTransportControls().skipToQueueItem(Long.valueOf(index));
-            mActivity.closeDrawer();
-        } else {
-            if (mItems == null) {
-                if (Log.isLoggable(TAG, Log.DEBUG)) {
-                    Log.d(TAG, "Media menu is empty.");
-                }
-                return;
-            }
-
-            for (MediaBrowser.MediaItem item : mItems) {
-                if (item.getMediaId().equals(id)) {
-                    if (item.isPlayable()) {
-                        if (mController != null) {
-                            mController.getTransportControls().pause();
-                            mController.getTransportControls().playFromMediaId(item.getMediaId(),
-                                    item.getDescription().getExtras());
-                        } else {
-                            Log.e(TAG, "MediaSession is destroyed.");
-                        }
-                        mActivity.closeDrawer();
-                    }
-                    break;
-                }
-            }
-        }
-    }
-
-    private void resetCarMenu(CarMenu result) {
-        // Stop loading previous menu due to we are under the new one now.
-        if (mMenuResult != null) {
-            if (mUpdateMenuRunnable != null) {
-                mHandler.removeCallbacks(mUpdateMenuRunnable);
-                // Spot fix. This runnable is being used in the subscription callbacks and is
-                // causing a crash. The lifecycle here is a little messed up and needs to be
-                // straightened out but for now just set it to a new object instead of setting
-                // it to null.
-                mUpdateMenuRunnable = new UpdateMenuRunnable();
-            }
-            if (mLoadMenuBitmapRunnable != null) {
-                mHandler.removeCallbacks(mLoadMenuBitmapRunnable);
-                mLoadMenuBitmapRunnable = null;
-            }
-            if (mLoadQueueBitmapRunnable != null) {
-                mHandler.removeCallbacks(mLoadQueueBitmapRunnable);
-                mLoadQueueBitmapRunnable = null;
-            }
-        }
-        mMenuResult = result;
-        mMenuResult.detach();
-    }
-
-    private CarMenu.Item emptyQueueMenu() {
-        CarMenu.Builder builder = new CarMenu.Builder(MEDIA_QUEUE_EMPTY_PLACEHOLDER);
-
-        final int iconColor = mContext.getResources().getColor(R.color.car_tint);
-        Drawable drawable = mContext.getResources().getDrawable(R.drawable.ic_list_view_disable);
-        drawable.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN);
-        builder.setIconFromSnapshot(drawable);
-        builder.setIsEmptyPlaceHolder(true);
-        return builder.build();
-    }
-
-    private void loadQueueMenu() {
-        if (mMenuResult == null) {
-            Log.w(TAG, "CarMenu is null while loading queue menu.");
-            return;
-        }
-
-        List<CarMenu.Item> menuItems = new ArrayList<>();
-        if (mController == null) {
-            Log.w(TAG, "MediaController is null while loading queue menu.");
-
-            // Add a icon for empty menu.
-            sendEmptyMenu();
-        } else {
-            List<MediaSession.QueueItem> queue = mController.getQueue();
-            mActiveQueueItemId = getActiveQueueItemId();
-            boolean hasImages = false;
-            for (MediaSession.QueueItem item : queue) {
-                if ((item.getDescription().getIconUri() != null)
-                        || (item.getDescription().getIconBitmap() != null)) {
-                    hasImages = true;
-                    break;
-                }
-            }
-            boolean activeQueueItemFound = false;
-            for (final MediaSession.QueueItem item : queue) {
-                // Only queue items following the active item are displayed in the menu.
-                if (item.getQueueId() == mActiveQueueItemId) {
-                    activeQueueItemFound = true;
-                }
-
-                if (activeQueueItemFound) {
-                    CarMenu.Builder builder =
-                            new CarMenu.Builder(QUEUE_ITEM_PREFIX + item.getQueueId());
-                    builder.setTitle(item.getDescription().getTitle().toString())
-                            .setText(item.getDescription().getSubtitle().toString());
-                    // Place empty bitmap as place holder first, we will load the bitamp later.
-                    if (hasImages) {
-                        builder.setIcon(null);
-                    }
-                    if (item.getQueueId() == mActiveQueueItemId) {
-                        int primaryColor =
-                                MediaManager.getInstance(mContext).getMediaClientPrimaryColor();
-                        Drawable drawable =
-                                mContext.getResources().getDrawable(R.drawable.ic_music_active);
-                        drawable.setColorFilter(primaryColor, PorterDuff.Mode.SRC_IN);
-                        builder.setRightIconFromSnapshot(drawable);
-                    }
-                    menuItems.add(builder.build());
-                }
-            }
-
-            // If we have not found any items then set the menu to empty placeholder item.
-            if (menuItems.size() == 0) {
-                sendEmptyMenu();
-            } else {
-                mMenuResult.sendResult(menuItems);
-                mMenuResult = null;
-            }
-
-            if (hasImages) {
-                if (mLoadQueueBitmapRunnable != null) {
-                    mHandler.removeCallbacks(mLoadQueueBitmapRunnable);
-                }
-                mLoadQueueBitmapRunnable = new LoadQueueBitmapRunnable(queue, QUEUE_ROOT);
-                mHandler.post(mLoadQueueBitmapRunnable);
-            }
-        }
-    }
-
-    private void sendEmptyMenu() {
-        if (mMenuResult != null) {
-            List<CarMenu.Item> menuItems = new ArrayList<CarMenu.Item>();
-            menuItems.add(emptyQueueMenu());
-            mMenuResult.sendResult(menuItems);
-            mMenuResult = null;
-        }
-    }
-
-    private boolean enableQueueItem(List<MediaSession.QueueItem> items) {
-        if (items == null || mController == null) {
-            return false;
-        }
-
-        if (mIsQueueInMenu) {
-            // We already have a queue item; do nothing
-            return false;
-        }
-        if (TextUtils.isEmpty(mController.getQueueTitle())) {
-            // No queue title to show; do nothing
-            return false;
-        }
-        return true;
-    }
-
-    private long getActiveQueueItemId() {
-        if (mController == null) {
-            return MediaSession.QueueItem.UNKNOWN_ID;
-        }
-
-        PlaybackState playbackState = mController.getPlaybackState();
-        if (playbackState != null) {
-            return playbackState.getActiveQueueItemId();
-        } else {
-            return MediaSession.QueueItem.UNKNOWN_ID;
-        }
-    }
-
-    private final MediaManager.Listener mListener = new MediaManager.Listener() {
-
-        @Override
-        public void onMediaAppChanged(ComponentName componentName) {
-            mRootId = null;
-            if (mBrowser != null) {
-                // Unsubscribe the old id first, or else it will affect to subscribe the new one.
-                if (!TextUtils.isEmpty(mMediaId) && !QUEUE_ROOT.equals(mMediaId)) {
-                    mBrowser.unsubscribe(mMediaId);
-                    mMediaId = null;
-                }
-                mBrowser.disconnect();
-                mBrowser = null;
-            }
-            Resources resources = mContext.getResources();
-            Bundle extras = new Bundle();
-            if (resources != null) {
-                extras.putInt(EXTRA_ICON_SIZE,
-                        resources.getDimensionPixelSize(R.dimen.car_list_item_icon_size));
-            }
-            mBrowser = new MediaBrowser(mContext, componentName, mConnectionCallbacks, extras);
-            if (mController != null) {
-                mController.unregisterCallback(mControllerCallback);
-                mController = null;
-            }
-            mBrowser.connect();
-            // Only store MediaManager instance to a local variable when it is short lived.
-            MediaManager mediaManager = MediaManager.getInstance(mContext);
-            mActivity.setTitle(mediaManager.getMediaClientName().toString());
-            mActivity.setScrimColor(mediaManager.getMediaClientPrimaryColorDark());
-            mActivity.attachContentFragment();
-        }
-
-        @Override
-        public void onStatusMessageChanged(String msg) {}
-    };
-
-    private final MediaBrowser.ConnectionCallback mConnectionCallbacks =
-            new MediaBrowser.ConnectionCallback() {
-
-        @Override
-        public void onConnected() {
-            // Get the real root and will replace it with the default fake one which is set
-            // in onGetRoot().
-            mRootId = mBrowser.getRoot();
-            if (mPendingMediaId != null) {
-                mMediaId = mPendingMediaId.equals(MEDIA_APP_ROOT) ? mRootId : mPendingMediaId;
-                mPendingMediaId = null;
-            } else {
-                mMediaId = mRootId;
-            }
-            MediaSession.Token token = mBrowser.getSessionToken();
-            if (token != null) {
-                mController = new MediaController(mContext, token);
-                mController.registerCallback(mControllerCallback);
-            } else {
-                // We will still be able to browse media content, but not able to play them.
-                Log.e(TAG, "Media session token is null for "
-                        + MediaManager.getInstance(mContext).getMediaClientName());
-            }
-            if (mLoadQueueMenuPending) {
-                mLoadQueueMenuPending = false;
-                loadQueueMenu();
-            } else {
-                mBrowser.subscribe(mMediaId, mSubscriptionCallback);
-            }
-        }
-
-        @Override
-        public void onConnectionSuspended() {
-            Log.w(TAG, "Media browser service connection suspended. Waiting to be"
-                    + " reconnected....");
-        }
-
-        @Override
-        public void onConnectionFailed() {
-            Log.e(TAG, "Media browser service connection FAILED!");
-            sendEmptyMenu();
-            // disconnect anyway to make sure we get into a sanity state
-            mBrowser.disconnect();
-            mBrowser = null;
-        }
-    };
-
-    private final MediaController.Callback mControllerCallback = new MediaController.Callback() {
-
-        @Override
-        public void onSessionDestroyed() {
-            Log.e(TAG, "Media session is destroyed");
-            sendEmptyMenu();
-            if (mController != null) {
-                mController.unregisterCallback(mControllerCallback);
-            }
-            mController = null;
-        }
-
-        @Override
-        public void onPlaybackStateChanged(PlaybackState state) {
-            long activeQueueItemId = getActiveQueueItemId();
-            if (mActiveQueueItemId != activeQueueItemId) {
-                if (mMediaId == QUEUE_ROOT) {
-                    // After this call, the whole queue menu will be refreshed.
-                    notifyChildrenChanged(QUEUE_ROOT);
-                }
-                mActiveQueueItemId = activeQueueItemId;
-            }
-        }
-
-        @Override
-        public void onQueueChanged(List<MediaSession.QueueItem> queue) {
-            if (mMediaId == mRootId && enableQueueItem(queue)) {
-                notifyChildrenChanged(MEDIA_APP_ROOT);
-            }
-        }
-    };
-
-    private final MediaBrowser.SubscriptionCallback mSubscriptionCallback =
-            new MediaBrowser.SubscriptionCallback() {
-
-        @Override
-        public void onChildrenLoaded(String parentId, List<MediaBrowser.MediaItem> children) {
-            Log.d(TAG, "onChildrenLoaded" + parentId);
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "Loaded " + children.size() + " children.");
-                for (MediaBrowser.MediaItem item : children) {
-                    Log.d(TAG, "\t" + item.getDescription().getTitle());
-                }
-            }
-
-            mIsQueueInMenu = false;
-            if (mController == null) {
-                if (Log.isLoggable(TAG, Log.DEBUG)) {
-                    Log.d(TAG, "MediaController is null in SubscriptionCallback.");
-                }
-                sendEmptyMenu();
-                // the session has been destroyed or we have moved to another facet.
-                return;
-            }
-
-            mItems = new ArrayList<>(children);
-            mHandler.removeCallbacks(mUpdateMenuRunnable);
-            mUpdateMenuRunnable.setParentId(parentId);
-            mHandler.post(mUpdateMenuRunnable);
-        }
-
-        @Override
-        public void onError(String mediaId) {
-            Log.e(TAG, "onError getting items for " + mediaId);
-            sendEmptyMenu();
-        }
-    };
-
-    private class UpdateMenuRunnable implements Runnable {
-        private String mParentId;
-
-        void setParentId(String parentId) {
-            mParentId = parentId;
-        }
-
-        @Override
-        public void run() {
-            if (mMenuResult == null) {
-                Log.e(TAG, "CarMenu is null while update menu, notify change instead.");
-                notifyChildrenChanged(mParentId);
-                return;
-            }
-
-            if (mItems == null) {
-                throw new IllegalArgumentException(
-                        "You must supply CarMenu with a list of MediaItems.");
-            }
-
-            boolean hasImages = false;
-            for (MediaBrowser.MediaItem item : mItems) {
-                if ((item.getDescription().getIconUri() != null)
-                        || (item.getDescription().getIconBitmap() != null)) {
-                    hasImages = true;
-                    break;
-                }
-            }
-            List<CarMenu.Item> menuItems = new ArrayList<>();
-            for (MediaBrowser.MediaItem item : mItems) {
-                menuItems.add(convertMediaItemToMenuItem(item, hasImages));
-            }
-            // If it is under root menu and play queue is not empty, add "Queue" item to the menu.
-            if (mMediaId.equals(mRootId) && mController != null) {
-                List<MediaSession.QueueItem> queue = mController.getQueue();
-                if (queue != null && queue.size() > 0
-                        && !TextUtils.isEmpty(mController.getQueueTitle())) {
-                    String queueTitle = mController.getQueueTitle().toString();
-                    menuItems.add(new CarMenu.Builder(QUEUE_ROOT).setTitle(queueTitle)
-                            .setFlags(CarMenuConstantsComapt.MenuItemConstants.FLAG_BROWSABLE)
-                            .build());
-                    mIsQueueInMenu = true;
-                }
-            }
-            if (menuItems.size() == 0) {
-                sendEmptyMenu();
-            } else {
-                mMenuResult.sendResult(menuItems);
-                mMenuResult = null;
-            }
-
-            if (hasImages) {
-                if (mLoadMenuBitmapRunnable != null) {
-                    mHandler.removeCallbacks(mLoadMenuBitmapRunnable);
-                }
-                // Due to we return fake root id in onGetRoot(), when we call notifyChildChanged()
-                // we still need to use the fake root id instead of the real one.
-                if (mMediaId.equals(mRootId)) {
-                    mLoadMenuBitmapRunnable = new LoadMenuBitmapRunnable(mItems, MEDIA_APP_ROOT);
-                } else {
-                    mLoadMenuBitmapRunnable = new LoadMenuBitmapRunnable(mItems, mMediaId);
-                }
-                mHandler.post(mLoadMenuBitmapRunnable);
-            }
-        }
-
-        /**
-         * Returns CarMenu.Item which is used in rendering menu.
-         *
-         * @param item MediaItem which has all info to render menu.
-         * @param hasImages Whether the menu item has image or not.
-         * @return menu item.
-         */
-        private CarMenu.Item convertMediaItemToMenuItem(MediaBrowser.MediaItem item,
-                boolean hasImages) {
-            CarMenu.Builder builder = new CarMenu.Builder(item.getMediaId());
-            CharSequence title = item.getDescription().getTitle();
-            if (title != null) {
-                builder.setTitle(title.toString());
-            }
-            CharSequence subTitle = item.getDescription().getSubtitle();
-            if (subTitle != null) {
-                builder.setText(subTitle.toString());
-            }
-            if (item.isBrowsable()) {
-                builder.setFlags(CarMenuConstantsComapt.MenuItemConstants.FLAG_BROWSABLE);
-            }
-            // Place empty bitmap as place holder first, we will load the bitamp later.
-            if (hasImages) {
-                builder.setIcon(null);
-            }
-            return builder.build();
-        }
-    }
-
-    private class LoadQueueBitmapRunnable implements Runnable {
-        private final List<MediaSession.QueueItem> mQueue;
-        private final String mParentId;
-
-        public LoadQueueBitmapRunnable(List<MediaSession.QueueItem> queue, String parentId) {
-            mQueue = queue;
-            mParentId = parentId;
-        }
-
-        @Override
-        public void run() {
-            boolean activeQueueItemFound = false;
-            for (MediaSession.QueueItem item : mQueue) {
-                if (item.getQueueId() == mActiveQueueItemId) {
-                    activeQueueItemFound = true;
-                }
-
-                if (activeQueueItemFound) {
-                    MediaMenuBitmapDownloader downloader = new MediaMenuBitmapDownloader(mContext,
-                            MediaCarMenuCallbacks.this, mParentId,
-                            QUEUE_ITEM_PREFIX + item.getQueueId(), mHandler);
-                    downloader.setMenuBitmap(item.getDescription());
-                }
-            }
-        }
-    }
-
-    private class LoadMenuBitmapRunnable implements Runnable {
-        private List<MediaBrowser.MediaItem> mItemList;
-        private String mParentId;
-
-        public LoadMenuBitmapRunnable(List<MediaBrowser.MediaItem> itemList, String parentId) {
-            mItemList = itemList;
-            mParentId = parentId;
-        }
-
-        @Override
-        public void run() {
-            for (MediaBrowser.MediaItem item : mItemList) {
-                MediaMenuBitmapDownloader downloader = new MediaMenuBitmapDownloader(mContext,
-                        MediaCarMenuCallbacks.this, mParentId, item.getMediaId(), mHandler);
-                downloader.setMenuBitmap(item.getDescription());
-            }
-        }
-    }
-}
diff --git a/src/com/android/car/media/MediaMenuBitmapDownloader.java b/src/com/android/car/media/MediaMenuBitmapDownloader.java
deleted file mode 100644
index ea8e370..0000000
--- a/src/com/android/car/media/MediaMenuBitmapDownloader.java
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.car.media;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.media.MediaDescription;
-import android.net.Uri;
-import android.os.Handler;
-import android.support.car.app.menu.CarMenu;
-import android.util.Log;
-import com.android.car.apps.common.BitmapDownloader;
-import com.android.car.apps.common.BitmapWorkerOptions;
-import com.android.car.apps.common.UriUtils;
-
-import java.lang.ref.WeakReference;
-
-/**
- * Download the icon for car menu item. Once it is done, it will update the icon by calling
- * CarMenuCallbacks.notifyChildChanged(), which is needed to be called after CarMenu.sendResult().
- */
-public class MediaMenuBitmapDownloader {
-    private static final String TAG = "GH.MBDownloader";
-    private static final int MAX_ALBUM_ART_DOWNLOAD_RETRIES = 10;
-    private static final long ALBUM_ART_DOWNLOAD_RETRY_INTERVAL_MS = 1000;
-
-    private final WeakReference<Context> mContext;
-    private final MediaCarMenuCallbacks mCallback;
-    private final String mParentId;
-    private final String mChildId;
-    private final Handler mHandler;
-    private BitmapDownloadRunnable mBitmapDownloadRunnable;
-
-    public MediaMenuBitmapDownloader(Context context, MediaCarMenuCallbacks callback,
-            String parentId, String childId, Handler handler) {
-        mContext = new WeakReference<>(context);
-        mCallback = callback;
-        mParentId = parentId;
-        mChildId = childId;
-        mHandler = handler;
-    }
-
-    public void setMenuBitmap(MediaDescription description) {
-        if (description == null) {
-            Log.w(TAG, "null media descriptor");
-            return;
-        }
-
-        if (mBitmapDownloadRunnable != null) {
-            mHandler.removeCallbacks(mBitmapDownloadRunnable);
-            mBitmapDownloadRunnable.cancelDownload();
-            mBitmapDownloadRunnable = null;
-        }
-
-        Bitmap bitmap = description.getIconBitmap();
-        Uri iconUri = description.getIconUri();
-        if (bitmap == null && iconUri == null) {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "no bitmap or icon uri found");
-            }
-        } else if (bitmap != null) {
-            updateIcon(bitmap);
-        } else {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.d(TAG, "downloading bitmap " + iconUri);
-            }
-            mBitmapDownloadRunnable = new BitmapDownloadRunnable(iconUri);
-            mHandler.post(mBitmapDownloadRunnable);
-        }
-    }
-
-    private void updateIcon(Bitmap bitmap) {
-        mCallback.notifyChildChanged(mParentId,
-                new CarMenu.Builder(mChildId).setIcon(bitmap).build());
-    }
-
-    private class BitmapDownloadRunnable implements Runnable {
-        private Uri mIconUri;
-        private int mRetries;
-        private BitmapDownloader.BitmapCallback mBitmapCallback;
-
-        public BitmapDownloadRunnable(Uri icon_uri) {
-            mIconUri = icon_uri;
-            mRetries = 0;
-        }
-
-        public void cancelDownload() {
-            if (mBitmapCallback != null) {
-                Context context = mContext.get();
-                if (context == null) {
-                    return;
-                }
-
-                BitmapDownloader.getInstance(context).cancelDownload(mBitmapCallback);
-            }
-        }
-
-        @Override
-        public void run() {
-            mBitmapCallback = new BitmapDownloader.BitmapCallback() {
-                @Override
-                public void onBitmapRetrieved(Bitmap bitmap) {
-                    if (bitmap == null) {
-                        if (++mRetries <= MAX_ALBUM_ART_DOWNLOAD_RETRIES) {
-                            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                                Log.d(TAG, "retrying after failing to download bitmap "
-                                        + mIconUri.toString());
-                            }
-                            mHandler.postDelayed(BitmapDownloadRunnable.this,
-                                    ALBUM_ART_DOWNLOAD_RETRY_INTERVAL_MS);
-                        }
-                    } else {
-                        if (Log.isLoggable(TAG, Log.DEBUG)) {
-                            Log.d(TAG, "downloaded bitmap " + mIconUri.toString() + " retries:"
-                                    + mRetries);
-                        }
-                        updateIcon(bitmap);
-                    }
-                }
-            };
-
-            Context context = mContext.get();
-            if (context == null) {
-                return;
-            }
-
-            int bitmapSize =
-                    context.getResources().getDimensionPixelSize(R.dimen.car_list_item_icon_size);
-            BitmapDownloader.getInstance(context)
-                    .getBitmap(
-                            new BitmapWorkerOptions.Builder(context).resource(mIconUri)
-                                    .height(bitmapSize)
-                                    .width(bitmapSize)
-                                    // We don't want to cache android resources as they are needed
-                                    // to be refreshed after configuration changes.
-                                    .cacheFlag(UriUtils.isAndroidResourceUri(mIconUri)
-                                            ? (BitmapWorkerOptions.CACHE_FLAG_DISK_DISABLED
-                                            | BitmapWorkerOptions.CACHE_FLAG_MEM_DISABLED)
-                                            : 0)
-                                    .build(),
-                            mBitmapCallback);
-        }
-    }
-}
diff --git a/src/com/android/car/media/MediaPlaybackFragment.java b/src/com/android/car/media/MediaPlaybackFragment.java
index 04bd846..8bd44f1 100644
--- a/src/com/android/car/media/MediaPlaybackFragment.java
+++ b/src/com/android/car/media/MediaPlaybackFragment.java
@@ -144,11 +144,10 @@
         mActivity = (MediaActivity) getHost();
         mShowTitleDelayMs =
                 mActivity.getResources().getInteger(R.integer.new_album_art_fade_in_offset);
-        mMediaPlaybackModel =
-                new MediaPlaybackModel(mActivity.getContext(), null /* browserExtras */);
+        mMediaPlaybackModel = new MediaPlaybackModel(mActivity, null /* browserExtras */);
         mMediaPlaybackModel.addListener(this);
-        mTelephonyManager = (TelephonyManager) mActivity.getContext()
-                .getSystemService(Context.TELEPHONY_SERVICE);
+        mTelephonyManager =
+                (TelephonyManager) mActivity.getSystemService(Context.TELEPHONY_SERVICE);
     }
 
     @Override
@@ -156,7 +155,6 @@
         super.onDestroy();
         mCurrentView = null;
         mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
-        mMediaPlaybackModel.onDestroy();
         mMediaPlaybackModel = null;
         mActivity = null;
         // Calling this with null will clear queue of callbacks and message.
@@ -237,7 +235,7 @@
     @Override
     public void onPause() {
         super.onPause();
-        mMediaPlaybackModel.onPause();
+        mMediaPlaybackModel.stop();
         mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
     }
 
@@ -252,7 +250,7 @@
     @Override
     public void onResume() {
         super.onResume();
-        mMediaPlaybackModel.onResume();
+        mMediaPlaybackModel.start();
         // Note: at registration, TelephonyManager will invoke the callback with the current state.
         mTelephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
     }
@@ -271,8 +269,7 @@
         int overflowViewColor = mMediaPlaybackModel.getPrimaryColorDark();
         mOverflowView.getBackground().setColorFilter(overflowViewColor, PorterDuff.Mode.SRC_IN);
         // Tint the overflow actions light or dark depending on contrast.
-        int overflowTintColor = ColorChecker.getTintColor(
-                mActivity.getContext(), overflowViewColor);
+        int overflowTintColor = ColorChecker.getTintColor(mActivity, overflowViewColor);
         for (ImageView v : mCustomActionButtons) {
             v.setColorFilter(overflowTintColor, PorterDuff.Mode.SRC_IN);
         }
@@ -335,7 +332,7 @@
             }
             showInitialNoContentView(state.getErrorMessage() != null ?
                     state.getErrorMessage().toString() :
-                    mActivity.getContext().getString(R.string.unknown_error), true);
+                    mActivity.getString(R.string.unknown_error), true);
             return;
         }
 
@@ -400,7 +397,6 @@
                     icon == null || mReturnFromOnStop ? 0 : mShowTitleDelayMs);
         }
         Uri iconUri = getMetadataIconUri(metadata);
-        Context context = mActivity.getContext();
         if (icon != null) {
             Bitmap scaledIcon = cropAlbumArt(icon);
             if (scaledIcon != icon && !icon.isRecycled()) {
@@ -412,7 +408,7 @@
             mActivity.setBackgroundBitmap(scaledIcon, !mReturnFromOnStop /* showAnimation */);
         } else if (iconUri != null) {
             if (mDownloader == null) {
-                mDownloader = new BitmapDownloader(context);
+                mDownloader = new BitmapDownloader(mActivity);
             }
             final int flags = BitmapWorkerOptions.CACHE_FLAG_DISK_DISABLED
                     | BitmapWorkerOptions.CACHE_FLAG_MEM_DISABLED;
@@ -420,7 +416,7 @@
                 Log.v(TAG, "Album art size " + mAlbumArtWidth + "x" + mAlbumArtHeight);
             }
 
-            mDownloader.getBitmap(new BitmapWorkerOptions.Builder(context).resource(iconUri)
+            mDownloader.getBitmap(new BitmapWorkerOptions.Builder(mActivity).resource(iconUri)
                             .height(mAlbumArtHeight).width(mAlbumArtWidth).cacheFlag(flags).build(),
                     new BitmapDownloader.BitmapCallback() {
                         @Override
@@ -505,7 +501,7 @@
                         }
                     });
 
-            int tint = ColorChecker.getTintColor(mActivity.getContext(),
+            int tint = ColorChecker.getTintColor(mActivity,
                     mMediaPlaybackModel.getPrimaryColorDark());
             mSeekBar.getProgressDrawable().setColorFilter(tint, PorterDuff.Mode.SRC_IN);
         } else {
@@ -870,9 +866,7 @@
             } else {
                 switch (v.getId()) {
                     case R.id.play_queue:
-                        CharSequence title = mMediaPlaybackModel.getQueueTitle();
-                        mActivity.showMenu(MediaCarMenuCallbacks.QUEUE_ROOT, title.toString());
-                        mActivity.openDrawer();
+                        mActivity.showQueueInDrawer();
                         break;
                     case R.id.prev:
                         transportControls.skipToPrevious();
diff --git a/src/com/android/car/media/MediaPlaybackModel.java b/src/com/android/car/media/MediaPlaybackModel.java
index 6f234e2..03a8817 100644
--- a/src/com/android/car/media/MediaPlaybackModel.java
+++ b/src/com/android/car/media/MediaPlaybackModel.java
@@ -46,7 +46,7 @@
  * main thread. Intended to provide a much more usable model interface to UI code.
  */
 public class MediaPlaybackModel {
-    private static final String TAG = "GH.MediaPlaybackModel";
+    private static final String TAG = "MediaPlaybackModel";
 
     private final Context mContext;
     private final Bundle mBrowserExtras;
@@ -55,6 +55,7 @@
     private Handler mHandler;
     private MediaController mController;
     private MediaBrowser mBrowser;
+    private int mPrimaryColor;
     private int mPrimaryColorDark;
     private int mAccentColor;
     private ComponentName mCurrentComponentName;
@@ -94,6 +95,29 @@
         void onSessionDestroyed(CharSequence destroyedMediaClientName);
     }
 
+    /** Convenient Listener base class for extension */
+    public static abstract class AbstractListener implements Listener {
+        @Override
+        public void onMediaAppChanged(@Nullable ComponentName currentName,
+                @Nullable ComponentName newName) {}
+        @Override
+        public void onMediaAppStatusMessageChanged(@Nullable String message) {}
+        @Override
+        public void onMediaConnected() {}
+        @Override
+        public void onMediaConnectionSuspended() {}
+        @Override
+        public void onMediaConnectionFailed(CharSequence failedMediaClientName) {}
+        @Override
+        public void onPlaybackStateChanged(@Nullable PlaybackState state) {}
+        @Override
+        public void onMetadataChanged(@Nullable MediaMetadata metadata) {}
+        @Override
+        public void onQueueChanged(List<MediaSession.QueueItem> queue) {}
+        @Override
+        public void onSessionDestroyed(CharSequence destroyedMediaClientName) {}
+    }
+
     public MediaPlaybackModel(Context context, Bundle browserExtras) {
         mContext = context;
         mBrowserExtras = browserExtras;
@@ -101,13 +125,13 @@
     }
 
     @MainThread
-    public void onDestroy() {
+    public void start() {
         Assert.isMainThread();
-        mHandler = null;
+        MediaManager.getInstance(mContext).addListener(mMediaManagerListener);
     }
 
     @MainThread
-    public void onPause() {
+    public void stop() {
         Assert.isMainThread();
         MediaManager.getInstance(mContext).removeListener(mMediaManagerListener);
         if (mBrowser != null) {
@@ -126,12 +150,6 @@
     }
 
     @MainThread
-    public void onResume() {
-        Assert.isMainThread();
-        MediaManager.getInstance(mContext).addListener(mMediaManagerListener);
-    }
-
-    @MainThread
     public void addListener(MediaPlaybackModel.Listener listener) {
         Assert.isMainThread();
         mListeners.add(listener);
@@ -146,8 +164,11 @@
     @MainThread
     private void notifyListeners(Consumer<Listener> callback) {
         Assert.isMainThread();
+        // Clone mListeners in case any of the callbacks made triggers a listener to be added or
+        // removed to/from mListeners.
+        List<Listener> listenersCopy = new LinkedList<>(mListeners);
         // Invokes callback.accept(listener) for each listener.
-        mListeners.forEach(callback);
+        listenersCopy.forEach(callback);
     }
 
     @MainThread
@@ -157,6 +178,12 @@
     }
 
     @MainThread
+    public int getPrimaryColor() {
+        Assert.isMainThread();
+        return mPrimaryColor;
+    }
+
+    @MainThread
     public int getAccentColor() {
         Assert.isMainThread();
         return mAccentColor;
@@ -227,6 +254,12 @@
     }
 
     @MainThread
+    public MediaBrowser getMediaBrowser() {
+        Assert.isMainThread();
+        return mBrowser;
+    }
+
+    @MainThread
     public MediaController.TransportControls getTransportControls() {
         Assert.isMainThread();
         if (mController == null) {
@@ -266,10 +299,10 @@
                 mBrowser.connect();
 
                 // reset the colors and views if we switch to another app.
-                mAccentColor = MediaManager.getInstance(mContext)
-                        .getMediaClientAccentColor();
-                mPrimaryColorDark = MediaManager.getInstance(mContext)
-                        .getMediaClientPrimaryColorDark();
+                MediaManager manager = MediaManager.getInstance(mContext);
+                mPrimaryColor = manager.getMediaClientPrimaryColor();
+                mAccentColor = manager.getMediaClientAccentColor();
+                mPrimaryColorDark = manager.getMediaClientPrimaryColorDark();
 
                 final ComponentName currentName = mCurrentComponentName;
                 notifyListeners((listener) -> listener.onMediaAppChanged(currentName, name));
diff --git a/src/com/android/car/media/MediaProxyActivity.java b/src/com/android/car/media/MediaProxyActivity.java
deleted file mode 100644
index c1950db..0000000
--- a/src/com/android/car/media/MediaProxyActivity.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- * Copyright (C) 2016 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 com.android.car.media;
-
-import android.support.car.app.CarProxyActivity;
-
-
-public class MediaProxyActivity extends CarProxyActivity {
-
-    public MediaProxyActivity() {
-        super(MediaActivity.class);
-    }
-}
diff --git a/src/com/android/car/media/drawer/MediaBrowserItemsFetcher.java b/src/com/android/car/media/drawer/MediaBrowserItemsFetcher.java
new file mode 100644
index 0000000..80bc5d7
--- /dev/null
+++ b/src/com/android/car/media/drawer/MediaBrowserItemsFetcher.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2017 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 com.android.car.media.drawer;
+
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.media.browse.MediaBrowser;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
+import android.util.Log;
+
+import com.android.car.app.CarDrawerActivity;
+import com.android.car.app.DrawerItemViewHolder;
+import com.android.car.media.MediaPlaybackModel;
+import com.android.car.media.R;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * {@link MediaItemsFetcher} implementation that fetches items from a specific {@link MediaBrowser}
+ * node.
+ * <p>
+ * It optionally supports surfacing the Media app's queue as the last item.
+ */
+class MediaBrowserItemsFetcher implements MediaItemsFetcher {
+    private static final String TAG = "Media.BrowserFetcher";
+
+    private final CarDrawerActivity mActivity;
+    private final MediaPlaybackModel mMediaPlaybackModel;
+    private final String mMediaId;
+    private final boolean mShowQueueItem;
+    private ItemsUpdatedCallback mCallback;
+    private List<MediaBrowser.MediaItem> mItems = new ArrayList<>();
+    private boolean mQueueAvailable;
+
+    MediaBrowserItemsFetcher(CarDrawerActivity activity, MediaPlaybackModel model, String mediaId,
+            boolean showQueueItem) {
+        mActivity = activity;
+        mMediaPlaybackModel = model;
+        mMediaId = mediaId;
+        mShowQueueItem = showQueueItem;
+    }
+
+    @Override
+    public void start(ItemsUpdatedCallback callback) {
+        mCallback = callback;
+        updateQueueAvailability();
+        mMediaPlaybackModel.getMediaBrowser().subscribe(mMediaId, mSubscriptionCallback);
+        mMediaPlaybackModel.addListener(mModelListener);
+    }
+
+    private final MediaPlaybackModel.Listener mModelListener =
+            new MediaPlaybackModel.AbstractListener() {
+        @Override
+        public void onQueueChanged(List<MediaSession.QueueItem> queue) {
+            updateQueueAvailability();
+        }
+        @Override
+        public void onSessionDestroyed(CharSequence destroyedMediaClientName) {
+            updateQueueAvailability();
+        }
+    };
+
+    private final MediaBrowser.SubscriptionCallback mSubscriptionCallback =
+        new MediaBrowser.SubscriptionCallback() {
+            @Override
+            public void onChildrenLoaded(String parentId, List<MediaBrowser.MediaItem> children) {
+                mItems.clear();
+                mItems.addAll(children);
+                mCallback.onItemsUpdated();
+            }
+
+            @Override
+            public void onError(String parentId) {
+                Log.e(TAG, "Error loading children of: " + mMediaId);
+                mItems.clear();
+                mCallback.onItemsUpdated();
+            }
+        };
+
+    private void updateQueueAvailability() {
+        if (mShowQueueItem && !mMediaPlaybackModel.getQueue().isEmpty()) {
+            mQueueAvailable = true;
+        }
+    }
+
+    @Override
+    public int getItemCount() {
+        int size = mItems.size();
+        if (mQueueAvailable) {
+            size++;
+        }
+        return size;
+    }
+
+    @Override
+    public void populateViewHolder(DrawerItemViewHolder holder, int position) {
+        if (mQueueAvailable && position == mItems.size()) {
+            holder.getTitle().setText(mMediaPlaybackModel.getQueueTitle());
+            return;
+        }
+        MediaBrowser.MediaItem item = mItems.get(position);
+        MediaItemsFetcher.populateViewHolderFrom(holder, item.getDescription());
+
+        // TODO(sriniv): Once we use smallLayout, text and rightIcon fields may be unavailable.
+        // Related to b/36573125.
+        if (item.isBrowsable()) {
+            int iconColor = mActivity.getColor(R.color.car_tint);
+            Drawable drawable = mActivity.getDrawable(R.drawable.ic_chevron_right);
+            drawable.setColorFilter(iconColor, PorterDuff.Mode.SRC_IN);
+            holder.getRightIcon().setImageDrawable(drawable);
+        } else {
+            holder.getRightIcon().setImageDrawable(null);
+        }
+    }
+
+    @Override
+    public void onItemClick(int position) {
+        if (mQueueAvailable && position == mItems.size()) {
+            MediaItemsFetcher fetcher = new MediaQueueItemsFetcher(mActivity, mMediaPlaybackModel);
+            setupAdapterAndSwitch(fetcher, mMediaPlaybackModel.getQueueTitle());
+            return;
+        }
+
+        MediaBrowser.MediaItem item = mItems.get(position);
+        if (item.isBrowsable()) {
+            MediaItemsFetcher fetcher = new MediaBrowserItemsFetcher(
+                    mActivity, mMediaPlaybackModel, item.getMediaId(), false /* showQueueItem */);
+            setupAdapterAndSwitch(fetcher, item.getDescription().getTitle());
+        } else if (item.isPlayable()) {
+            MediaController.TransportControls controls = mMediaPlaybackModel.getTransportControls();
+            if (controls != null) {
+                controls.pause();
+                controls.playFromMediaId(item.getMediaId(), item.getDescription().getExtras());
+            }
+            mActivity.closeDrawer();
+        } else {
+            Log.w(TAG, "Unknown item type; don't know how to handle!");
+        }
+    }
+
+    private void setupAdapterAndSwitch(MediaItemsFetcher fetcher, CharSequence title) {
+        MediaDrawerAdapter subAdapter = new MediaDrawerAdapter(mActivity, false /* smallLayout */);
+        subAdapter.setFetcher(fetcher);
+        subAdapter.setTitle(title);
+        mActivity.switchToAdapter(subAdapter);
+    }
+
+    @Override
+    public void cleanup() {
+        mMediaPlaybackModel.removeListener(mModelListener);
+        mMediaPlaybackModel.getMediaBrowser().unsubscribe(mMediaId);
+        mCallback = null;
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/car/media/drawer/MediaDrawerAdapter.java b/src/com/android/car/media/drawer/MediaDrawerAdapter.java
new file mode 100644
index 0000000..dc483a2
--- /dev/null
+++ b/src/com/android/car/media/drawer/MediaDrawerAdapter.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2017 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 com.android.car.media.drawer;
+
+import com.android.car.app.CarDrawerActivity;
+import com.android.car.app.CarDrawerAdapter;
+import com.android.car.app.DrawerItemViewHolder;
+
+/**
+ * Subclass of CarDrawerAdapter used by the Media app.
+ * <p>
+ * This adapter delegates actual fetching of items (and other operations) to a
+ * {@link MediaItemsFetcher}. The current fetcher being used can be updated at runtime.
+ */
+class MediaDrawerAdapter extends CarDrawerAdapter {
+    private final CarDrawerActivity mActivity;
+    private MediaItemsFetcher mCurrentFetcher;
+
+    MediaDrawerAdapter(CarDrawerActivity activity, boolean useSmallLayout) {
+        super(activity, true /* showDisabledListOnEmpty */, useSmallLayout);
+        mActivity = activity;
+    }
+
+    /**
+     * Switch the {@link MediaItemsFetcher} being used to fetch items. The new fetcher is kicked-off
+     * and the drawer's content's will be updated to show newly loaded items. Any old fetcher is
+     * cleaned up and released.
+     *
+     * @param fetcher New {@link MediaItemsFetcher} to use for display Drawer items.
+     */
+    void setFetcher(MediaItemsFetcher fetcher) {
+        if (mCurrentFetcher != null) {
+            mCurrentFetcher.cleanup();
+        }
+        mCurrentFetcher = fetcher;
+        mCurrentFetcher.start(() -> {
+            mActivity.showLoadingProgressBar(false);
+            notifyDataSetChanged();
+        });
+        // Initially there will be no items and we don't want to show empty-list indicator briefly
+        // until items are fetched.
+        mActivity.showLoadingProgressBar(true);
+    }
+
+    @Override
+    protected int getActualItemCount() {
+        return mCurrentFetcher != null ? mCurrentFetcher.getItemCount() : 0;
+    }
+
+    @Override
+    protected void populateViewHolder(DrawerItemViewHolder holder, int position) {
+        if (mCurrentFetcher != null) {
+            mCurrentFetcher.populateViewHolder(holder, position);
+        }
+    }
+
+    @Override
+    public void onItemClick(int position) {
+        if (mCurrentFetcher != null) {
+            mCurrentFetcher.onItemClick(position);
+        }
+    }
+}
diff --git a/src/com/android/car/media/drawer/MediaDrawerController.java b/src/com/android/car/media/drawer/MediaDrawerController.java
new file mode 100644
index 0000000..e1715bd
--- /dev/null
+++ b/src/com/android/car/media/drawer/MediaDrawerController.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright (C) 2017 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 com.android.car.media.drawer;
+
+import android.content.ComponentName;
+import android.os.Bundle;
+import android.support.annotation.Nullable;
+import android.support.v4.widget.DrawerLayout;
+import android.view.View;
+
+import com.android.car.app.CarDrawerActivity;
+import com.android.car.app.CarDrawerAdapter;
+import com.android.car.media.MediaManager;
+import com.android.car.media.MediaPlaybackModel;
+import com.android.car.media.R;
+
+/**
+ * Manages overall Drawer functionality.
+ * <p>
+ * Maintains separate MediaPlaybackModel for media browsing and control. Sets up root Drawer
+ * adapter with root of media-browse tree (using MediaBrowserItemsFetcher). Supports switching the
+ * rootAdapter to show the queue-items (using MediaQueueItemsFetcher).
+ */
+public class MediaDrawerController {
+    private static final String TAG = "MediaDrawerController";
+    private static final String EXTRA_ICON_SIZE =
+            "com.google.android.gms.car.media.BrowserIconSize";
+
+    private final CarDrawerActivity mActivity;
+    private final MediaPlaybackModel mMediaPlaybackModel;
+    private MediaDrawerAdapter mRootAdapter;
+
+    public MediaDrawerController(CarDrawerActivity activity) {
+        mActivity = activity;
+        Bundle extras = new Bundle();
+        extras.putInt(EXTRA_ICON_SIZE,
+                mActivity.getResources().getDimensionPixelSize(R.dimen.car_list_item_icon_size));
+        mMediaPlaybackModel = new MediaPlaybackModel(mActivity, extras);
+        mMediaPlaybackModel.addListener(mModelListener);
+
+        // TODO(sriniv): Needs smallLayout below. But breaks when showing queue items (b/36573125).
+        mRootAdapter = new MediaDrawerAdapter(mActivity, false /* useSmallLayout */);
+        // Start with a empty title since we depend on the mMediaManagerListener callback to
+        // know which app is being used and set the actual title there.
+        mRootAdapter.setTitle("");
+
+        // Kick off MediaBrowser/MediaController connection.
+        mMediaPlaybackModel.start();
+    }
+
+    public void cleanup() {
+        mRootAdapter.cleanup();
+        mMediaPlaybackModel.stop();
+    }
+
+    /**
+     * @return Adapter to display root items of MediaBrowse tree. {@link #showQueueInDrawer()} can
+     *      be used to display items from the queue.
+     */
+    public CarDrawerAdapter getRootAdapter() {
+        return mRootAdapter;
+    }
+
+    private MediaItemsFetcher createRootMediaItemsFetcher() {
+        return new MediaBrowserItemsFetcher(mActivity, mMediaPlaybackModel,
+                mMediaPlaybackModel.getMediaBrowser().getRoot(), true /* showQueueItem */);
+    }
+
+    private final MediaPlaybackModel.Listener mModelListener =
+            new MediaPlaybackModel.AbstractListener() {
+        @Override
+        public void onMediaAppChanged(@Nullable ComponentName currentName,
+                @Nullable ComponentName newName) {
+            // Only store MediaManager instance to a local variable when it is short lived.
+            MediaManager mediaManager = MediaManager.getInstance(mActivity);
+            mRootAdapter.setTitle(mediaManager.getMediaClientName());
+        }
+
+        @Override
+        public void onMediaConnected() {
+            mRootAdapter.setFetcher(createRootMediaItemsFetcher());
+        }
+    };
+
+    /**
+     * Switch the rootAdapter to show items from the currently playing Queue and open the drawer.
+     * When the drawer is closed, the adapter items are switched back to media-browse root.
+     */
+    public void showQueueInDrawer() {
+        mRootAdapter.setFetcher(new MediaQueueItemsFetcher(mActivity, mMediaPlaybackModel));
+        mRootAdapter.setTitle(mMediaPlaybackModel.getQueueTitle());
+        mActivity.openDrawer();
+        mActivity.addDrawerListener(new DrawerLayout.DrawerListener() {
+            @Override
+            public void onDrawerClosed(View drawerView) {
+                mRootAdapter.setFetcher(createRootMediaItemsFetcher());
+                mActivity.removeDrawerListener(this);
+                mRootAdapter.setTitle(
+                        MediaManager.getInstance(mActivity).getMediaClientName());
+            }
+
+            @Override
+            public void onDrawerSlide(View drawerView, float slideOffset) {}
+            @Override
+            public void onDrawerOpened(View drawerView) {}
+            @Override
+            public void onDrawerStateChanged(int newState) {}
+        });
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/car/media/drawer/MediaItemsFetcher.java b/src/com/android/car/media/drawer/MediaItemsFetcher.java
new file mode 100644
index 0000000..a712f7b
--- /dev/null
+++ b/src/com/android/car/media/drawer/MediaItemsFetcher.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2017 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 com.android.car.media.drawer;
+
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.media.MediaDescription;
+
+import com.android.car.app.DrawerItemViewHolder;
+import com.android.car.apps.common.BitmapDownloader;
+import com.android.car.apps.common.BitmapWorkerOptions;
+import com.android.car.apps.common.UriUtils;
+import com.android.car.media.R;
+
+/**
+ * Component that handles fetching of items for {@link MediaDrawerAdapter}.
+ * <p>
+ * It also handles ViewHolder population and item clicks.
+ */
+interface MediaItemsFetcher {
+    /**
+     * Used to inform owning {@link MediaDrawerAdapter} that items have changed.
+     */
+    interface ItemsUpdatedCallback {
+        void onItemsUpdated();
+    }
+
+    /**
+     * Kick-off fetching/monitoring of items.
+     *
+     * @param callback Callback that is invoked when items are first loaded ar if they change
+     *                 subsequently.
+     */
+    void start(ItemsUpdatedCallback callback);
+
+    /**
+     * @return Number of items currently fetched.
+     */
+    int getItemCount();
+
+    /**
+     * Used by owning {@link MediaDrawerAdapter} to populate views.
+     *
+     * @param holder View-holder to populate.
+     * @param position Item position.
+     */
+    void populateViewHolder(DrawerItemViewHolder holder, int position);
+
+    /**
+     * Used by owning {@link MediaDrawerAdapter} to handle clicks.
+     *
+     * @param position Item position.
+     */
+    void onItemClick(int position);
+
+    /**
+     * Used when this instance is going to be released. Subclasses should release resources.
+     */
+    void cleanup();
+
+    /**
+     * Utility method to populate {@code holder} with details from {@code description}. It populates
+     * title, text and icon at most.
+     */
+    static void populateViewHolderFrom(DrawerItemViewHolder holder, MediaDescription description) {
+        Context context = holder.itemView.getContext();
+        // TODO(sriniv): Once we use smallLayout, text and rightIcon fields may be unavailable.
+        // Related to b/36573125.
+        holder.getTitle().setText(description.getTitle());
+        holder.getText().setText(description.getSubtitle());
+        Bitmap iconBitmap = description.getIconBitmap();
+        holder.getIcon().setImageBitmap(iconBitmap);    // Ok to set null here for clearing.
+        if (iconBitmap == null && description.getIconUri() != null) {
+            int bitmapSize =
+                    context.getResources().getDimensionPixelSize(R.dimen.car_list_item_icon_size);
+            // We don't want to cache android resources as they are needed to be refreshed after
+            // configuration changes.
+            int cacheFlag = UriUtils.isAndroidResourceUri(description.getIconUri())
+                    ? (BitmapWorkerOptions.CACHE_FLAG_DISK_DISABLED
+                    | BitmapWorkerOptions.CACHE_FLAG_MEM_DISABLED)
+                    : 0;
+            BitmapWorkerOptions options = new BitmapWorkerOptions.Builder(context)
+                    .resource(description.getIconUri())
+                    .height(bitmapSize)
+                    .width(bitmapSize)
+                    .cacheFlag(cacheFlag)
+                    .build();
+            BitmapDownloader.getInstance(context).loadBitmap(options, holder.getIcon());
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/com/android/car/media/drawer/MediaQueueItemsFetcher.java b/src/com/android/car/media/drawer/MediaQueueItemsFetcher.java
new file mode 100644
index 0000000..d27d092
--- /dev/null
+++ b/src/com/android/car/media/drawer/MediaQueueItemsFetcher.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright (C) 2017 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 com.android.car.media.drawer;
+
+import android.graphics.PorterDuff;
+import android.graphics.drawable.Drawable;
+import android.media.session.MediaController;
+import android.media.session.MediaSession;
+import android.media.session.PlaybackState;
+import android.os.Handler;
+import android.support.annotation.Nullable;
+
+import com.android.car.app.CarDrawerActivity;
+import com.android.car.app.DrawerItemViewHolder;
+import com.android.car.media.MediaPlaybackModel;
+import com.android.car.media.R;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * {@link MediaItemsFetcher} implementation that fetches items from the {@link MediaController}'s
+ * currently playing queue.
+ */
+class MediaQueueItemsFetcher implements MediaItemsFetcher {
+    private static final String TAG = "MediaQueueItemsFetcher";
+
+    private final Handler mHandler = new Handler();
+    private final CarDrawerActivity mActivity;
+    private MediaPlaybackModel mMediaPlaybackModel;
+    private ItemsUpdatedCallback mCallback;
+    private List<MediaSession.QueueItem> mItems = new ArrayList<>();
+
+    MediaQueueItemsFetcher(CarDrawerActivity activity, MediaPlaybackModel model) {
+        mActivity = activity;
+        mMediaPlaybackModel = model;
+    }
+
+    @Override
+    public void start(ItemsUpdatedCallback callback) {
+        mCallback = callback;
+        if (mMediaPlaybackModel != null) {
+            mMediaPlaybackModel.addListener(listener);
+            updateItemsFrom(mMediaPlaybackModel.getQueue());
+        }
+        // Inform client of current items. Invoke async to avoid re-entrancy issues.
+        mHandler.post(mCallback::onItemsUpdated);
+    }
+
+    @Override
+    public int getItemCount() {
+        return mItems.size();
+    }
+
+    @Override
+    public void populateViewHolder(DrawerItemViewHolder holder, int position) {
+        MediaSession.QueueItem item = mItems.get(position);
+        MediaItemsFetcher.populateViewHolderFrom(holder, item.getDescription());
+
+        if (item.getQueueId() == getActiveQueueItemId()) {
+            int primaryColor = mMediaPlaybackModel.getPrimaryColor();
+            Drawable drawable =
+                    mActivity.getResources().getDrawable(R.drawable.ic_music_active);
+            drawable.setColorFilter(primaryColor, PorterDuff.Mode.SRC_IN);
+            holder.getRightIcon().setImageDrawable(drawable);
+        } else {
+            holder.getRightIcon().setImageBitmap(null);
+        }
+    }
+
+    @Override
+    public void onItemClick(int position) {
+        MediaController.TransportControls controls = mMediaPlaybackModel.getTransportControls();
+        if (controls != null) {
+            controls.skipToQueueItem(mItems.get(position).getQueueId());
+        }
+        mActivity.closeDrawer();
+    }
+
+    @Override
+    public void cleanup() {
+        mMediaPlaybackModel.removeListener(listener);
+    }
+
+    private void updateItemsFrom(List<MediaSession.QueueItem> queue) {
+        mItems.clear();
+        // We only show items starting from active-item in the queue.
+        final long activeItemId = getActiveQueueItemId();
+        boolean activeItemFound = false;
+        for (MediaSession.QueueItem item : queue) {
+            if (activeItemId == item.getQueueId()) {
+                activeItemFound = true;
+            }
+            if (activeItemFound) {
+                mItems.add(item);
+            }
+        }
+    }
+
+    private long getActiveQueueItemId() {
+        if (mMediaPlaybackModel != null) {
+            PlaybackState playbackState = mMediaPlaybackModel.getPlaybackState();
+            if (playbackState != null) {
+                return playbackState.getActiveQueueItemId();
+            }
+        }
+        return MediaSession.QueueItem.UNKNOWN_ID;
+    }
+
+    private final MediaPlaybackModel.Listener listener = new MediaPlaybackModel.AbstractListener() {
+        @Override
+        public void onQueueChanged(List<MediaSession.QueueItem> queue) {
+            updateItemsFrom(queue);
+            mCallback.onItemsUpdated();
+        }
+
+        @Override
+        public void onPlaybackStateChanged(@Nullable PlaybackState state) {
+            // Since active playing item may have changed, force re-draw of queue items.
+            mCallback.onItemsUpdated();
+        }
+
+        @Override
+        public void onSessionDestroyed(CharSequence destroyedMediaClientName) {
+            onQueueChanged(Collections.emptyList());
+        }
+    };
+}
