diff --git a/Android.mk b/Android.mk
index 1cdc709..80b860b 100644
--- a/Android.mk
+++ b/Android.mk
@@ -330,12 +330,6 @@
 	media/java/android/media/projection/IMediaProjectionCallback.aidl \
 	media/java/android/media/projection/IMediaProjectionManager.aidl \
 	media/java/android/media/projection/IMediaProjectionWatcherCallback.aidl \
-	media/java/android/media/routing/IMediaRouteService.aidl \
-	media/java/android/media/routing/IMediaRouteClientCallback.aidl \
-	media/java/android/media/routing/IMediaRouter.aidl \
-	media/java/android/media/routing/IMediaRouterDelegate.aidl \
-	media/java/android/media/routing/IMediaRouterRoutingCallback.aidl \
-	media/java/android/media/routing/IMediaRouterStateCallback.aidl \
 	media/java/android/media/session/IActiveSessionsListener.aidl \
 	media/java/android/media/session/ISessionController.aidl \
 	media/java/android/media/session/ISessionControllerCallback.aidl \
@@ -497,7 +491,6 @@
 	frameworks/base/location/java/com/android/internal/location/ProviderRequest.aidl \
 	frameworks/base/media/java/android/media/MediaMetadata.aidl \
 	frameworks/base/media/java/android/media/Rating.aidl \
-	frameworks/base/media/java/android/media/routing/MediaRouteSelector.aidl \
 	frameworks/base/media/java/android/media/session/MediaSession.aidl \
 	frameworks/base/media/java/android/media/session/PlaybackState.aidl \
 	frameworks/base/telephony/java/android/telephony/ServiceState.aidl \
diff --git a/api/current.txt b/api/current.txt
index b2106d2..516a2b6 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -23,7 +23,6 @@
     field public static final java.lang.String BIND_DEVICE_ADMIN = "android.permission.BIND_DEVICE_ADMIN";
     field public static final java.lang.String BIND_DREAM_SERVICE = "android.permission.BIND_DREAM_SERVICE";
     field public static final java.lang.String BIND_INPUT_METHOD = "android.permission.BIND_INPUT_METHOD";
-    field public static final java.lang.String BIND_MEDIA_ROUTE_SERVICE = "android.permission.BIND_MEDIA_ROUTE_SERVICE";
     field public static final java.lang.String BIND_NFC_SERVICE = "android.permission.BIND_NFC_SERVICE";
     field public static final java.lang.String BIND_NOTIFICATION_LISTENER_SERVICE = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
     field public static final java.lang.String BIND_PRINT_SERVICE = "android.permission.BIND_PRINT_SERVICE";
@@ -16380,242 +16379,6 @@
 
 }
 
-package android.media.routing {
-
-  public final class MediaRouteSelector implements android.os.Parcelable {
-    method public boolean containsProtocol(java.lang.Class<?>);
-    method public boolean containsProtocol(java.lang.String);
-    method public int describeContents();
-    method public android.os.Bundle getExtras();
-    method public int getOptionalFeatures();
-    method public java.util.List<java.lang.String> getOptionalProtocols();
-    method public int getRequiredFeatures();
-    method public java.util.List<java.lang.String> getRequiredProtocols();
-    method public java.lang.String getServicePackageName();
-    method public void writeToParcel(android.os.Parcel, int);
-    field public static final android.os.Parcelable.Creator CREATOR;
-  }
-
-  public static final class MediaRouteSelector.Builder {
-    ctor public MediaRouteSelector.Builder();
-    method public android.media.routing.MediaRouteSelector.Builder addOptionalProtocol(java.lang.Class<?>);
-    method public android.media.routing.MediaRouteSelector.Builder addOptionalProtocol(java.lang.String);
-    method public android.media.routing.MediaRouteSelector.Builder addRequiredProtocol(java.lang.Class<?>);
-    method public android.media.routing.MediaRouteSelector.Builder addRequiredProtocol(java.lang.String);
-    method public android.media.routing.MediaRouteSelector build();
-    method public android.media.routing.MediaRouteSelector.Builder setExtras(android.os.Bundle);
-    method public android.media.routing.MediaRouteSelector.Builder setOptionalFeatures(int);
-    method public android.media.routing.MediaRouteSelector.Builder setRequiredFeatures(int);
-    method public android.media.routing.MediaRouteSelector.Builder setServicePackageName(java.lang.String);
-  }
-
-  public abstract class MediaRouteService extends android.app.Service {
-    ctor public MediaRouteService();
-    method public android.media.routing.MediaRouter.ServiceMetadata getServiceMetadata();
-    method public android.os.IBinder onBind(android.content.Intent);
-    method public abstract android.media.routing.MediaRouteService.ClientSession onCreateClientSession(android.media.routing.MediaRouteService.ClientInfo);
-    field public static final java.lang.String SERVICE_INTERFACE = "android.media.routing.MediaRouteService";
-  }
-
-  public static final class MediaRouteService.ClientInfo {
-    method public java.lang.String getPackageName();
-    method public int getUid();
-  }
-
-  public static abstract class MediaRouteService.ClientSession {
-    ctor public MediaRouteService.ClientSession();
-    method public abstract boolean onConnect(android.media.routing.MediaRouter.ConnectionRequest, android.media.routing.MediaRouteService.ConnectionCallback);
-    method public abstract void onDisconnect();
-    method public void onPauseStream();
-    method public void onRelease();
-    method public void onResumeStream();
-    method public abstract boolean onStartDiscovery(android.media.routing.MediaRouter.DiscoveryRequest, android.media.routing.MediaRouteService.DiscoveryCallback);
-    method public abstract void onStopDiscovery();
-  }
-
-  public final class MediaRouteService.ConnectionCallback {
-    method public void onConnected(android.media.routing.MediaRouter.ConnectionInfo);
-    method public void onConnectionFailed(int, java.lang.CharSequence, android.os.Bundle);
-    method public void onDisconnected();
-  }
-
-  public final class MediaRouteService.DiscoveryCallback {
-    method public void onDestinationFound(android.media.routing.MediaRouter.DestinationInfo, java.util.List<android.media.routing.MediaRouter.RouteInfo>);
-    method public void onDestinationLost(android.media.routing.MediaRouter.DestinationInfo);
-    method public void onDiscoveryFailed(int, java.lang.CharSequence, android.os.Bundle);
-  }
-
-  public final class MediaRouter {
-    ctor public MediaRouter(android.content.Context);
-    method public void addSelector(android.media.routing.MediaRouteSelector);
-    method public void clearSelectors();
-    method public android.media.routing.MediaRouter.Delegate createDelegate();
-    method public android.media.routing.MediaRouter.ConnectionInfo getConnection();
-    method public int getConnectionState();
-    method public java.util.List<android.media.routing.MediaRouter.DestinationInfo> getDiscoveredDestinations();
-    method public java.util.List<android.media.routing.MediaRouter.RouteInfo> getDiscoveredRoutes(android.media.routing.MediaRouter.DestinationInfo);
-    method public int getDiscoveryState();
-    method public android.media.AudioAttributes getPreferredAudioAttributes();
-    method public android.view.Display getPreferredPresentationDisplay();
-    method public android.media.VolumeProvider getPreferredVolumeProvider();
-    method public android.media.routing.MediaRouter.DestinationInfo getSelectedDestination();
-    method public android.media.routing.MediaRouter.RouteInfo getSelectedRoute();
-    method public java.util.List<android.media.routing.MediaRouteSelector> getSelectors();
-    method public boolean isReleased();
-    method public void pauseStream();
-    method public void release();
-    method public void removeSelector(android.media.routing.MediaRouteSelector);
-    method public void resumeStream();
-    method public void setRoutingCallback(android.media.routing.MediaRouter.RoutingCallback, android.os.Handler);
-    field public static final int CONNECTION_ERROR_ABORTED = 1; // 0x1
-    field public static final int CONNECTION_ERROR_BARGED = 7; // 0x7
-    field public static final int CONNECTION_ERROR_BROKEN = 6; // 0x6
-    field public static final int CONNECTION_ERROR_BUSY = 4; // 0x4
-    field public static final int CONNECTION_ERROR_TIMEOUT = 5; // 0x5
-    field public static final int CONNECTION_ERROR_UNAUTHORIZED = 2; // 0x2
-    field public static final int CONNECTION_ERROR_UNKNOWN = 0; // 0x0
-    field public static final int CONNECTION_ERROR_UNREACHABLE = 3; // 0x3
-    field public static final int CONNECTION_FLAG_BARGE = 1; // 0x1
-    field public static final int CONNECTION_STATE_CONNECTED = 2; // 0x2
-    field public static final int CONNECTION_STATE_CONNECTING = 1; // 0x1
-    field public static final int CONNECTION_STATE_DISCONNECTED = 0; // 0x0
-    field public static final int DISCONNECTION_REASON_APPLICATION_REQUEST = 0; // 0x0
-    field public static final int DISCONNECTION_REASON_ERROR = 2; // 0x2
-    field public static final int DISCONNECTION_REASON_USER_REQUEST = 1; // 0x1
-    field public static final int DISCOVERY_ERROR_ABORTED = 1; // 0x1
-    field public static final int DISCOVERY_ERROR_NO_CONNECTIVITY = 2; // 0x2
-    field public static final int DISCOVERY_ERROR_UNKNOWN = 0; // 0x0
-    field public static final int DISCOVERY_FLAG_BACKGROUND = 1; // 0x1
-    field public static final int DISCOVERY_STATE_STARTED = 1; // 0x1
-    field public static final int DISCOVERY_STATE_STOPPED = 0; // 0x0
-    field public static final int ROUTE_FEATURE_LIVE_AUDIO = 1; // 0x1
-    field public static final int ROUTE_FEATURE_LIVE_VIDEO = 2; // 0x2
-  }
-
-  public static final class MediaRouter.ConnectionInfo {
-    method public android.media.AudioAttributes getAudioAttributes();
-    method public android.os.Bundle getExtras();
-    method public int getFeatures();
-    method public android.view.Display getPresentationDisplay();
-    method public android.os.IBinder getProtocolBinder(java.lang.String);
-    method public android.os.IBinder getProtocolBinder(int);
-    method public T getProtocolObject(java.lang.Class<T>);
-    method public java.util.List<java.lang.String> getProtocols();
-    method public android.media.routing.MediaRouter.RouteInfo getRoute();
-    method public android.media.VolumeProvider getVolumeProvider();
-  }
-
-  public static final class MediaRouter.ConnectionInfo.Builder {
-    ctor public MediaRouter.ConnectionInfo.Builder(android.media.routing.MediaRouter.RouteInfo);
-    method public android.media.routing.MediaRouter.ConnectionInfo build();
-    method public android.media.routing.MediaRouter.ConnectionInfo.Builder setAudioAttributes(android.media.AudioAttributes);
-    method public android.media.routing.MediaRouter.ConnectionInfo.Builder setExtras(android.os.Bundle);
-    method public android.media.routing.MediaRouter.ConnectionInfo.Builder setPresentationDisplay(android.view.Display);
-    method public android.media.routing.MediaRouter.ConnectionInfo.Builder setProtocolBinder(java.lang.String, android.os.IBinder);
-    method public android.media.routing.MediaRouter.ConnectionInfo.Builder setProtocolStub(java.lang.Class<?>, android.os.IInterface);
-    method public android.media.routing.MediaRouter.ConnectionInfo.Builder setVolumeProvider(android.media.VolumeProvider);
-  }
-
-  public static final class MediaRouter.ConnectionRequest {
-    method public android.os.Bundle getExtras();
-    method public int getFlags();
-    method public android.media.routing.MediaRouter.RouteInfo getRoute();
-    method public void setExtras(android.os.Bundle);
-    method public void setFlags(int);
-    method public void setRoute(android.media.routing.MediaRouter.RouteInfo);
-  }
-
-  public static final class MediaRouter.Delegate {
-    ctor public MediaRouter.Delegate();
-    method public void addStateCallback(android.media.routing.MediaRouter.StateCallback, android.os.Handler);
-    method public void connect(android.media.routing.MediaRouter.DestinationInfo, int);
-    method public void disconnect(int);
-    method public int getConnectionState();
-    method public java.util.List<android.media.routing.MediaRouter.DestinationInfo> getDiscoveredDestinations();
-    method public int getDiscoveryState();
-    method public android.media.routing.MediaRouter.DestinationInfo getSelectedDestination();
-    method public boolean isReleased();
-    method public void removeStateCallback(android.media.routing.MediaRouter.StateCallback);
-    method public void startDiscovery(int);
-    method public void stopDiscovery();
-  }
-
-  public static final class MediaRouter.DestinationInfo {
-    method public java.lang.CharSequence getDescription();
-    method public android.os.Bundle getExtras();
-    method public int getIconResourceId();
-    method public java.lang.String getId();
-    method public java.lang.CharSequence getName();
-    method public android.media.routing.MediaRouter.ServiceMetadata getServiceMetadata();
-    method public android.graphics.drawable.Drawable loadIcon(android.content.pm.PackageManager);
-  }
-
-  public static final class MediaRouter.DestinationInfo.Builder {
-    ctor public MediaRouter.DestinationInfo.Builder(java.lang.String, android.media.routing.MediaRouter.ServiceMetadata, java.lang.CharSequence);
-    method public android.media.routing.MediaRouter.DestinationInfo build();
-    method public android.media.routing.MediaRouter.DestinationInfo.Builder setDescription(java.lang.CharSequence);
-    method public android.media.routing.MediaRouter.DestinationInfo.Builder setExtras(android.os.Bundle);
-    method public android.media.routing.MediaRouter.DestinationInfo.Builder setIconResourceId(int);
-  }
-
-  public static final class MediaRouter.DiscoveryRequest {
-    method public int getFlags();
-    method public java.util.List<android.media.routing.MediaRouteSelector> getSelectors();
-    method public void setFlags(int);
-    method public void setSelectors(java.util.List<android.media.routing.MediaRouteSelector>);
-  }
-
-  public static final class MediaRouter.RouteInfo {
-    method public android.media.routing.MediaRouter.DestinationInfo getDestination();
-    method public android.os.Bundle getExtras();
-    method public int getFeatures();
-    method public java.lang.String getId();
-    method public java.util.List<java.lang.String> getProtocols();
-    method public android.media.routing.MediaRouteSelector getSelector();
-  }
-
-  public static final class MediaRouter.RouteInfo.Builder {
-    ctor public MediaRouter.RouteInfo.Builder(java.lang.String, android.media.routing.MediaRouter.DestinationInfo, android.media.routing.MediaRouteSelector);
-    method public android.media.routing.MediaRouter.RouteInfo.Builder addProtocol(java.lang.Class<T>);
-    method public android.media.routing.MediaRouter.RouteInfo.Builder addProtocol(java.lang.String);
-    method public android.media.routing.MediaRouter.RouteInfo build();
-    method public android.media.routing.MediaRouter.RouteInfo.Builder setExtras(android.os.Bundle);
-    method public android.media.routing.MediaRouter.RouteInfo.Builder setFeatures(int);
-  }
-
-  public static abstract class MediaRouter.RoutingCallback extends android.media.routing.MediaRouter.StateCallback {
-    ctor public MediaRouter.RoutingCallback();
-    method public boolean onPrepareConnectionRequest(android.media.routing.MediaRouter.ConnectionRequest, android.media.routing.MediaRouter.DestinationInfo, java.util.List<android.media.routing.MediaRouter.RouteInfo>);
-    method public boolean onPrepareDiscoveryRequest(android.media.routing.MediaRouter.DiscoveryRequest, java.util.List<android.media.routing.MediaRouteSelector>);
-  }
-
-  public static final class MediaRouter.ServiceMetadata {
-    method public android.content.ComponentName getComponentName();
-    method public android.graphics.drawable.Drawable getIcon(android.content.pm.PackageManager);
-    method public java.lang.CharSequence getLabel(android.content.pm.PackageManager);
-    method public java.lang.String getPackageName();
-    method public android.content.pm.ServiceInfo getService();
-  }
-
-  public static abstract class MediaRouter.StateCallback {
-    ctor public MediaRouter.StateCallback();
-    method public void onConnected();
-    method public void onConnecting();
-    method public void onConnectionFailed(int, java.lang.CharSequence, android.os.Bundle);
-    method public void onConnectionStateChanged(int);
-    method public void onDestinationFound(android.media.routing.MediaRouter.DestinationInfo);
-    method public void onDestinationLost(android.media.routing.MediaRouter.DestinationInfo);
-    method public void onDisconnected();
-    method public void onDiscoveryFailed(int, java.lang.CharSequence, android.os.Bundle);
-    method public void onDiscoveryStarted();
-    method public void onDiscoveryStateChanged(int);
-    method public void onDiscoveryStopped();
-    method public void onReleased();
-    method public void onSelectedDestinationChanged(android.media.routing.MediaRouter.DestinationInfo);
-  }
-
-}
-
 package android.media.session {
 
   public final class MediaController {
@@ -16623,7 +16386,6 @@
     method public void addCallback(android.media.session.MediaController.Callback);
     method public void addCallback(android.media.session.MediaController.Callback, android.os.Handler);
     method public void adjustVolume(int, int);
-    method public android.media.routing.MediaRouter.Delegate createMediaRouterDelegate();
     method public boolean dispatchMediaButtonEvent(android.view.KeyEvent);
     method public android.media.session.MediaController.AudioInfo getAudioInfo();
     method public android.os.Bundle getExtras();
@@ -16693,7 +16455,6 @@
     method public void setFlags(int);
     method public void setLaunchActivity(android.app.PendingIntent);
     method public void setMediaButtonReceiver(android.app.PendingIntent);
-    method public void setMediaRouter(android.media.routing.MediaRouter);
     method public void setMetadata(android.media.MediaMetadata);
     method public void setPlaybackState(android.media.session.PlaybackState);
     method public void setPlaybackToLocal(android.media.AudioAttributes);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 5e77d28..52f1dd9 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -305,7 +305,7 @@
 
     /**
      * Activity Action: Show settings to allow configuration of
-     * {@link android.media.routing.MediaRouteService media route providers}.
+     * cast endpoints.
      * <p>
      * In some cases, a matching Activity may not exist, so ensure you
      * safeguard against this.
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 157147e..7809c71 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -2210,14 +2210,6 @@
         android:description="@string/permdesc_modifyParentalControls"
         android:protectionLevel="signature" />
 
-    <!-- Must be required by a {@link android.media.routing.MediaRouteService}
-         to ensure that only the system can interact with it.
-         @hide -->
-    <permission android:name="android.permission.BIND_ROUTE_PROVIDER"
-        android:label="@string/permlab_bindRouteProvider"
-        android:description="@string/permdesc_bindRouteProvider"
-        android:protectionLevel="signature" />
-
     <!-- Must be required by device administration receiver, to ensure that only the
          system can interact with it. -->
     <permission android:name="android.permission.BIND_DEVICE_ADMIN"
@@ -2783,13 +2775,6 @@
         android:description="@string/permdesc_bindConditionProviderService"
         android:protectionLevel="signature" />
 
-    <!-- Must be required by a {@link android.media.routing.MediaRouteService},
-         to ensure that only the system can bind to it. -->
-    <permission android:name="android.permission.BIND_MEDIA_ROUTE_SERVICE"
-        android:label="@string/permlab_bindMediaRouteService"
-        android:description="@string/permdesc_bindMediaRouteService"
-        android:protectionLevel="signature" />
-
     <!-- Must be required by an {@link android.service.dreams.DreamService},
          to ensure that only the system can bind to it. -->
     <permission android:name="android.permission.BIND_DREAM_SERVICE"
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 2936e2b..78ba738 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1160,12 +1160,6 @@
         interface of a widget service. Should never be needed for normal apps.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permlab_bindRouteProvider">bind to a route provider service</string>
-    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_bindRouteProvider">Allows the holder to bind to any registered
-        route providers. Should never be needed for normal apps.</string>
-
-    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_bindDeviceAdmin">interact with a device admin</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_bindDeviceAdmin">Allows the holder to send intents to
@@ -2157,11 +2151,6 @@
     <string name="permdesc_bindConditionProviderService">Allows the holder to bind to the top-level interface of a condition provider service. Should never be needed for normal apps.</string>
 
     <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permlab_bindMediaRouteService">bind to a media route service</string>
-    <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
-    <string name="permdesc_bindMediaRouteService">Allows the holder to bind to the top-level interface of a media route service. Should never be needed for normal apps.</string>
-
-    <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permlab_bindDreamService">bind to a dream service</string>
     <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
     <string name="permdesc_bindDreamService">Allows the holder to bind to the top-level interface of a dream service. Should never be needed for normal apps.</string>
diff --git a/media/java/android/media/routing/IMediaRouteClientCallback.aidl b/media/java/android/media/routing/IMediaRouteClientCallback.aidl
deleted file mode 100644
index d90ea3b..0000000
--- a/media/java/android/media/routing/IMediaRouteClientCallback.aidl
+++ /dev/null
@@ -1,41 +0,0 @@
-/* Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.routing;
-
-import android.media.routing.MediaRouteSelector;
-import android.media.routing.ParcelableConnectionInfo;
-import android.media.routing.ParcelableDestinationInfo;
-import android.media.routing.ParcelableRouteInfo;
-import android.os.IBinder;
-import android.os.Bundle;
-
-/**
- * @hide
- */
-oneway interface IMediaRouteClientCallback {
-    void onDestinationFound(int seq, in ParcelableDestinationInfo destination,
-            in ParcelableRouteInfo[] routes);
-
-    void onDestinationLost(int seq, String id);
-
-    void onDiscoveryFailed(int seq, int error, in CharSequence message, in Bundle extras);
-
-    void onConnected(int seq, in ParcelableConnectionInfo connection);
-
-    void onDisconnected(int seq);
-
-    void onConnectionFailed(int seq, int error, in CharSequence message, in Bundle extras);
-}
diff --git a/media/java/android/media/routing/IMediaRouteService.aidl b/media/java/android/media/routing/IMediaRouteService.aidl
deleted file mode 100644
index 493ab6d..0000000
--- a/media/java/android/media/routing/IMediaRouteService.aidl
+++ /dev/null
@@ -1,46 +0,0 @@
-/* Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.routing;
-
-import android.media.routing.IMediaRouteClientCallback;
-import android.media.routing.MediaRouteSelector;
-import android.os.Bundle;
-
-/**
- * Interface to an app's MediaRouteService.
- * @hide
- */
-oneway interface IMediaRouteService {
-    void registerClient(int clientUid, String clientPackageName,
-            in IMediaRouteClientCallback callback);
-
-    void unregisterClient(in IMediaRouteClientCallback callback);
-
-    void startDiscovery(in IMediaRouteClientCallback callback, int seq,
-            in List<MediaRouteSelector> selectors, int flags);
-
-    void stopDiscovery(in IMediaRouteClientCallback callback);
-
-    void connect(in IMediaRouteClientCallback callback, int seq,
-            String destinationId, String routeId, int flags, in Bundle extras);
-
-    void disconnect(in IMediaRouteClientCallback callback);
-
-    void pauseStream(in IMediaRouteClientCallback callback);
-
-    void resumeStream(in IMediaRouteClientCallback callback);
-}
-
diff --git a/media/java/android/media/routing/IMediaRouter.aidl b/media/java/android/media/routing/IMediaRouter.aidl
deleted file mode 100644
index 0abb258..0000000
--- a/media/java/android/media/routing/IMediaRouter.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.routing;
-
-/** @hide */
-interface IMediaRouter {
-
-}
-
diff --git a/media/java/android/media/routing/IMediaRouterDelegate.aidl b/media/java/android/media/routing/IMediaRouterDelegate.aidl
deleted file mode 100644
index 35f84c8..0000000
--- a/media/java/android/media/routing/IMediaRouterDelegate.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.routing;
-
-/** @hide */
-interface IMediaRouterDelegate {
-
-}
-
diff --git a/media/java/android/media/routing/IMediaRouterRoutingCallback.aidl b/media/java/android/media/routing/IMediaRouterRoutingCallback.aidl
deleted file mode 100644
index 173ae55..0000000
--- a/media/java/android/media/routing/IMediaRouterRoutingCallback.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.routing;
-
-/** @hide */
-interface IMediaRouterRoutingCallback {
-
-}
-
diff --git a/media/java/android/media/routing/IMediaRouterStateCallback.aidl b/media/java/android/media/routing/IMediaRouterStateCallback.aidl
deleted file mode 100644
index 0299904..0000000
--- a/media/java/android/media/routing/IMediaRouterStateCallback.aidl
+++ /dev/null
@@ -1,22 +0,0 @@
-/* Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.media.routing;
-
-/** @hide */
-interface IMediaRouterStateCallback {
-
-}
-
diff --git a/media/java/android/media/routing/MediaRouteSelector.aidl b/media/java/android/media/routing/MediaRouteSelector.aidl
deleted file mode 100644
index 37bfa4a..0000000
--- a/media/java/android/media/routing/MediaRouteSelector.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 2014, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.media.routing;
-
-parcelable MediaRouteSelector;
diff --git a/media/java/android/media/routing/MediaRouteSelector.java b/media/java/android/media/routing/MediaRouteSelector.java
deleted file mode 100644
index 26a9b1c..0000000
--- a/media/java/android/media/routing/MediaRouteSelector.java
+++ /dev/null
@@ -1,357 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.media.routing;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.media.routing.MediaRouter.RouteFeatures;
-import android.os.Bundle;
-import android.os.IInterface;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * A media route selector consists of a set of constraints that are used to select
- * the routes to which an application would like to connect.  The constraints consist
- * of a set of required or optional features and protocols.  The constraints may also
- * require the use of a specific media route service package or additional characteristics
- * that are described by a bundle of extra parameters.
- * <p>
- * The application will typically create several different selectors that express
- * various combinations of characteristics that it would like to use together when
- * it connects to a destination media device.  For each destination that is discovered,
- * media route services will publish some number of routes and include information
- * about which selector each route matches.  The application will then choose among
- * these routes to determine which best satisfies its desired purpose and connect to it.
- * </p>
- */
-public final class MediaRouteSelector implements Parcelable {
-    private final int mRequiredFeatures;
-    private final int mOptionalFeatures;
-    private final List<String> mRequiredProtocols;
-    private final List<String> mOptionalProtocols;
-    private final String mServicePackageName;
-    private final Bundle mExtras;
-
-    MediaRouteSelector(int requiredFeatures, int optionalFeatures,
-            List<String> requiredProtocols, List<String> optionalProtocols,
-            String servicePackageName, Bundle extras) {
-        mRequiredFeatures = requiredFeatures;
-        mOptionalFeatures = optionalFeatures;
-        mRequiredProtocols = requiredProtocols;
-        mOptionalProtocols = optionalProtocols;
-        mServicePackageName = servicePackageName;
-        mExtras = extras;
-    }
-
-    /**
-     * Gets the set of required route features.
-     *
-     * @return A set of required route feature flags.
-     */
-    public @RouteFeatures int getRequiredFeatures() {
-        return mRequiredFeatures;
-    }
-
-    /**
-     * Gets the set of optional route features.
-     *
-     * @return A set of optional route feature flags.
-     */
-    public @RouteFeatures int getOptionalFeatures() {
-        return mOptionalFeatures;
-    }
-
-    /**
-     * Gets the list of route protocols that a route must support in order to be selected.
-     * <p>
-     * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
-     * for more information.
-     * </p>
-     *
-     * @return The list of fully qualified route protocol names.
-     */
-    public @NonNull List<String> getRequiredProtocols() {
-        return mRequiredProtocols;
-    }
-
-    /**
-     * Gets the list of optional route protocols that a client may use if they are available.
-     * <p>
-     * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
-     * for more information.
-     * </p>
-     *
-     * @return The list of optional fully qualified route protocol names.
-     */
-    public @NonNull List<String> getOptionalProtocols() {
-        return mOptionalProtocols;
-    }
-
-    /**
-     * Returns true if the selector includes a required or optional request for
-     * the specified protocol using its fully qualified class name.
-     * <p>
-     * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
-     * for more information.
-     * </p>
-     *
-     * @param clazz The protocol class.
-     * @return True if the protocol was requested.
-     */
-    public boolean containsProtocol(@NonNull Class<?> clazz) {
-        return containsProtocol(clazz.getName());
-    }
-
-    /**
-     * Returns true if the selector includes a required or optional request for
-     * the specified protocol.
-     * <p>
-     * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
-     * for more information.
-     * </p>
-     *
-     * @param name The name of the protocol.
-     * @return True if the protocol was requested.
-     */
-    public boolean containsProtocol(@NonNull String name) {
-        return mRequiredProtocols.contains(name)
-                || mOptionalProtocols.contains(name);
-    }
-
-    /**
-     * Gets the package name of a specific media route service that this route selector
-     * requires.
-     *
-     * @return The required media route service package name, or null if none.
-     */
-    public @Nullable String getServicePackageName() {
-        return mServicePackageName;
-    }
-
-    /**
-     * Gets optional extras that may be used to select or configure routes for a
-     * particular purpose.  Some extras may be used by media route services to apply
-     * additional constraints or parameters for the routes to be discovered.
-     *
-     * @return The optional extras, or null if none.
-     */
-    public @Nullable Bundle getExtras() {
-        return mExtras;
-    }
-
-    @Override
-    public String toString() {
-        return "MediaRouteSelector{ "
-                + ", requiredFeatures=0x" + Integer.toHexString(mRequiredFeatures)
-                + ", optionalFeatures=0x" + Integer.toHexString(mOptionalFeatures)
-                + ", requiredProtocols=" + mRequiredProtocols
-                + ", optionalProtocols=" + mOptionalProtocols
-                + ", servicePackageName=" + mServicePackageName
-                + ", extras=" + mExtras + " }";
-    }
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeInt(mRequiredFeatures);
-        dest.writeInt(mOptionalFeatures);
-        dest.writeStringList(mRequiredProtocols);
-        dest.writeStringList(mOptionalProtocols);
-        dest.writeString(mServicePackageName);
-        dest.writeBundle(mExtras);
-    }
-
-    public static final Parcelable.Creator<MediaRouteSelector> CREATOR =
-            new Parcelable.Creator<MediaRouteSelector>() {
-        @Override
-        public MediaRouteSelector createFromParcel(Parcel source) {
-            int requiredFeatures = source.readInt();
-            int optionalFeatures = source.readInt();
-            ArrayList<String> requiredProtocols = new ArrayList<String>();
-            ArrayList<String> optionalProtocols = new ArrayList<String>();
-            source.readStringList(requiredProtocols);
-            source.readStringList(optionalProtocols);
-            return new MediaRouteSelector(requiredFeatures, optionalFeatures,
-                    requiredProtocols, optionalProtocols,
-                    source.readString(), source.readBundle());
-        }
-
-        @Override
-        public MediaRouteSelector[] newArray(int size) {
-            return new MediaRouteSelector[size];
-        }
-    };
-
-    /**
-     * Builder for {@link MediaRouteSelector} objects.
-     */
-    public static final class Builder {
-        private int mRequiredFeatures;
-        private int mOptionalFeatures;
-        private final ArrayList<String> mRequiredProtocols = new ArrayList<String>();
-        private final ArrayList<String> mOptionalProtocols = new ArrayList<String>();
-        private String mServicePackageName;
-        private Bundle mExtras;
-
-        /**
-         * Creates an initially empty selector builder.
-         */
-        public Builder() {
-        }
-
-        /**
-         * Sets the set of required route features.
-         *
-         * @param features A set of required route feature flags.
-         */
-        public @NonNull Builder setRequiredFeatures(@RouteFeatures int features) {
-            mRequiredFeatures = features;
-            return this;
-        }
-
-        /**
-         * Sets the set of optional route features.
-         *
-         * @param features A set of optional route feature flags.
-         */
-        public @NonNull Builder setOptionalFeatures(@RouteFeatures int features) {
-            mOptionalFeatures = features;
-            return this;
-        }
-
-        /**
-         * Adds a route protocol that a route must support in order to be selected
-         * using its fully qualified class name.
-         * <p>
-         * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
-         * for more information.
-         * </p>
-         *
-         * @param clazz The protocol class.
-         * @return this
-         */
-        public @NonNull Builder addRequiredProtocol(@NonNull Class<?> clazz) {
-            if (clazz == null) {
-                throw new IllegalArgumentException("clazz must not be null");
-            }
-            return addRequiredProtocol(clazz.getName());
-        }
-
-        /**
-         * Adds a route protocol that a route must support in order to be selected.
-         * <p>
-         * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
-         * for more information.
-         * </p>
-         *
-         * @param name The fully qualified name of the required protocol.
-         * @return this
-         */
-        public @NonNull Builder addRequiredProtocol(@NonNull String name) {
-            if (TextUtils.isEmpty(name)) {
-                throw new IllegalArgumentException("name must not be null or empty");
-            }
-            mRequiredProtocols.add(name);
-            return this;
-        }
-
-        /**
-         * Adds an optional route protocol that a client may use if available
-         * using its fully qualified class name.
-         * <p>
-         * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
-         * for more information.
-         * </p>
-         *
-         * @param clazz The protocol class.
-         * @return this
-         */
-        public @NonNull Builder addOptionalProtocol(@NonNull Class<?> clazz) {
-            if (clazz == null) {
-                throw new IllegalArgumentException("clazz must not be null");
-            }
-            return addOptionalProtocol(clazz.getName());
-        }
-
-        /**
-         * Adds an optional route protocol that a client may use if available.
-         * <p>
-         * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
-         * for more information.
-         * </p>
-         *
-         * @param name The fully qualified name of the optional protocol.
-         * @return this
-         */
-        public @NonNull Builder addOptionalProtocol(@NonNull String name) {
-            if (TextUtils.isEmpty(name)) {
-                throw new IllegalArgumentException("name must not be null or empty");
-            }
-            mOptionalProtocols.add(name);
-            return this;
-        }
-
-        /**
-         * Sets the package name of the media route service to which this selector
-         * appertains.
-         * <p>
-         * If a package name is specified here then this selector will only be
-         * passed to media route services from that package.  This has the effect
-         * of restricting the set of matching routes to just those that are offered
-         * by that package.
-         * </p>
-         *
-         * @param packageName The required service package name, or null if none.
-         * @return this
-         */
-        public @NonNull Builder setServicePackageName(@Nullable String packageName) {
-            mServicePackageName = packageName;
-            return this;
-        }
-
-        /**
-         * Sets optional extras that may be used to select or configure routes for a
-         * particular purpose.  Some extras may be used by route services to specify
-         * additional constraints or parameters for the routes to be discovered.
-         *
-         * @param extras The optional extras, or null if none.
-         * @return this
-         */
-        public @NonNull Builder setExtras(@Nullable Bundle extras) {
-            mExtras = extras;
-            return this;
-        }
-
-        /**
-         * Builds the {@link MediaRouteSelector} object.
-         *
-         * @return The new media route selector instance.
-         */
-        public @NonNull MediaRouteSelector build() {
-            return new MediaRouteSelector(mRequiredFeatures, mOptionalFeatures,
-                    mRequiredProtocols, mOptionalProtocols, mServicePackageName, mExtras);
-        }
-    }
-}
diff --git a/media/java/android/media/routing/MediaRouteService.java b/media/java/android/media/routing/MediaRouteService.java
deleted file mode 100644
index 4d5a8a9..0000000
--- a/media/java/android/media/routing/MediaRouteService.java
+++ /dev/null
@@ -1,1023 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.media.routing;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SdkConstant;
-import android.app.Service;
-import android.content.Intent;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.media.routing.MediaRouter.ConnectionError;
-import android.media.routing.MediaRouter.ConnectionInfo;
-import android.media.routing.MediaRouter.ConnectionRequest;
-import android.media.routing.MediaRouter.DestinationInfo;
-import android.media.routing.MediaRouter.DiscoveryError;
-import android.media.routing.MediaRouter.DiscoveryRequest;
-import android.media.routing.MediaRouter.RouteInfo;
-import android.media.routing.MediaRouter.ServiceMetadata;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.RemoteException;
-import android.util.ArrayMap;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Media route services implement strategies for discovering
- * and establishing connections to media devices and their routes.  These services
- * are also known as media route providers.
- * <p>
- * Each media route service subclass is responsible for enabling applications
- * and the system to interact with media devices of some kind.
- * For example, one particular media route service implementation might
- * offer support for discovering nearby wireless display devices and streaming
- * video contents to them; another media route service implementation might
- * offer support for discovering nearby speakers and streaming media appliances
- * and sending commands to play content on request.
- * </p><p>
- * Subclasses must override the {@link #onCreateClientSession} method to return
- * a {@link ClientSession} object that implements the {@link ClientSession#onStartDiscovery},
- * {@link ClientSession#onStopDiscovery}, and {@link ClientSession#onConnect} methods
- * to allow clients to discover and connect to media devices.
- * </p><p>
- * This object is not thread-safe.  All callbacks are invoked on the main looper.
- * </p>
- *
- * <h3>Clients</h3>
- * <p>
- * The clients of this API are media applications that would like to discover
- * and connect to media devices.  The client may also be the system, such as
- * when the user initiates display mirroring via the Cast Screen function.
- * </p><p>
- * There may be multiple client sessions active at the same time.  Each client
- * session can request discovery and connect to routes independently of any
- * other client.  It is the responsibility of the media route service to maintain
- * separate state for each client session and to ensure that clients cannot interfere
- * with one another in harmful ways.
- * </p><p>
- * Notwithstanding the requirement to support any number of concurrent client
- * sessions, the media route service may impose constraints on how many clients
- * can connect to the same media device in a particular mode at the same time.
- * In some cases, media devices may support connections from an arbitrary number
- * of clients simultaneously but often it may be necessary to ensure that only
- * one client is in control.  When this happens, the media route service should
- * report a connection error unless the connection request specifies that the
- * client should take control of the media device (and forcibly disconnect other
- * clients that may be using it).
- * </p>
- *
- * <h3>Destinations</h3>
- * <p>
- * The media devices to which an application may send media content are referred
- * to in the API as destinations.  Each destination therefore represents a single
- * independent device such as a speaker or TV set.  Destinations are given meaningful
- * names and descriptions to help the user associate them with devices in their
- * environment.
- * </p><p>
- * Destinations may be local or remote and may be accessed through various means,
- * often wirelessly.  The user may install media route services to enable
- * media applications to connect to a variety of destinations with different
- * capabilities.
- * </p>
- *
- * <h3>Routes</h3>
- * <p>
- * Routes represent possible usages or means of reaching and interacting with
- * a destination.  Since destinations may support many different features, they may
- * each offer multiple routes for applications to choose from based on their needs.
- * For example, one route might express the ability to stream locally rendered audio
- * and video to the device; another route might express the ability to send a URL for
- * the destination to download from the network and play all by itself.
- * </p><p>
- * Routes are discovered according to the set of capabilities that
- * an application or the system is seeking to use at a particular time.  For example,
- * if an application wants to stream music to a destination then it will ask the
- * {@link MediaRouter} to find routes to destinations can stream music and ignore
- * all other destinations that cannot.
- * </p><p>
- * In general, the application will inspect the set of routes that have been
- * offered then connect to the most appropriate route for its desired purpose.
- * </p>
- *
- * <h3>Discovery</h3>
- * <p>
- * Discovery is the process of finding destinations based on a description of the
- * kinds of routes that an application or the system would like to use.
- * </p><p>
- * Discovery begins when {@link ClientSession#onStartDiscovery} is called and ends when
- * {@link ClientSession#onStopDiscovery} is called.  There may be multiple simultaneous
- * discovery requests in progress at the same time from different clients.  It is up to
- * the media route service to perform these requests in parallel or multiplex them
- * as required.
- * </p><p>
- * Media route services are <em>strongly encouraged</em> to use the information
- * in the discovery request to optimize discovery and avoid redundant work.
- * In the case where no media device supported by the media route service
- * could possibly offer the requested capabilities, the
- * {@link ClientSession#onStartDiscovery} method should return <code>false</code> to
- * let the system know that it can unbind from the media route service and
- * release its resources.
- * </p>
- *
- * <h3>Settings</h3>
- * <p>
- * Many kinds of devices can be discovered on demand simply by scanning the local network
- * or using wireless protocols such as Bluetooth to find them.  However, in some cases
- * it may be necessary for the user to manually configure destinations before they
- * can be used (or to adjust settings later).  Actual user configuration of destinations
- * is beyond the scope of this API but media route services may specify an activity
- * in their manifest that the user can launch to perform these tasks.
- * </p><p>
- * Note that media route services that are installed from the store must be enabled
- * by the user before they become available for applications to use.
- * The {@link android.provider.Settings#ACTION_CAST_SETTINGS Settings.ACTION_CAST_SETTINGS}
- * settings activity provides the ability for the user to configure media route services.
- * </p>
- *
- * <h3>Manifest Declaration</h3>
- * <p>
- * Media route services must be declared in the manifest along with meta-data
- * about the kinds of routes that they are capable of discovering.  The system
- * uses this information to optimize the set of services to which it binds in
- * order to satisfy a particular discovery request.
- * </p><p>
- * To extend this class, you must declare the service in your manifest file with
- * the {@link android.Manifest.permission#BIND_MEDIA_ROUTE_SERVICE} permission
- * and include an intent filter with the {@link #SERVICE_INTERFACE} action.  You must
- * also add meta-data to describe the kinds of routes that your service is capable
- * of discovering.
- * </p><p>
- * For example:
- * </p><pre>
- * &lt;service android:name=".MediaRouteProvider"
- *          android:label="&#64;string/service_name"
- *          android:permission="android.permission.BIND_MEDIA_ROUTE_SERVICE">
- *     &lt;intent-filter>
- *         &lt;action android:name="android.media.routing.MediaRouteService" />
- *     &lt;/intent-filter>
- *
- *     TODO: INSERT METADATA DECLARATIONS HERE
- *
- * &lt;/service>
- * </pre>
- */
-public abstract class MediaRouteService extends Service {
-    private static final String TAG = "MediaRouteService";
-
-    private static final boolean DEBUG = true;
-
-    private final Handler mHandler;
-    private final BinderService mService;
-    private final ArrayMap<IBinder, ClientRecord> mClientRecords =
-            new ArrayMap<IBinder, ClientRecord>();
-
-    private ServiceMetadata mMetadata;
-
-    /**
-     * The {@link Intent} that must be declared as handled by the service.
-     */
-    @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
-    public static final String SERVICE_INTERFACE =
-            "android.media.routing.MediaRouteService";
-
-    /**
-     * Creates a media route service.
-     */
-    public MediaRouteService() {
-        mHandler = new Handler(true);
-        mService = new BinderService();
-    }
-
-    @Override
-    public @Nullable IBinder onBind(Intent intent) {
-        if (SERVICE_INTERFACE.equals(intent.getAction())) {
-            return mService;
-        }
-        return null;
-    }
-
-    /**
-     * Creates a new client session on behalf of a client.
-     * <p>
-     * The implementation should return a {@link ClientSession} for the client
-     * to use.  The media route service must take care to manage the state of
-     * each client session independently from any others that might also be
-     * in use at the same time.
-     * </p>
-     *
-     * @param client Information about the client.
-     * @return The client session object, or null if the client is not allowed
-     * to interact with this media route service.
-     */
-    public abstract @Nullable ClientSession onCreateClientSession(@NonNull ClientInfo client);
-
-    /**
-     * Gets metadata about this service.
-     * <p>
-     * Use this method to obtain a {@link ServiceMetadata} object to provide when creating
-     * a {@link android.media.routing.MediaRouter.DestinationInfo.Builder}.
-     * </p>
-     *
-     * @return Metadata about this service.
-     */
-    public @NonNull ServiceMetadata getServiceMetadata() {
-        if (mMetadata == null) {
-            try {
-                mMetadata = new ServiceMetadata(this);
-            } catch (NameNotFoundException ex) {
-                Log.wtf(TAG, "Could not retrieve own service metadata!");
-            }
-        }
-        return mMetadata;
-    }
-
-    /**
-     * Enables a single client to access the functionality of the media route service.
-     */
-    public static abstract class ClientSession {
-        /**
-         * Starts discovery.
-         * <p>
-         * If the media route service is capable of discovering routes that satisfy
-         * the request then this method should start discovery and return true.
-         * Otherwise, this method should return false.  If false is returned,
-         * then the framework will not call {@link #onStopDiscovery} since discovery
-         * was never actually started.
-         * </p><p>
-         * There may already be other discovery requests in progress at the same time
-         * for other clients; the media route service must keep track of them all.
-         * </p>
-         *
-         * @param req The discovery request to start.
-         * @param callback A callback to receive discovery events related to this
-         * particular request.  The events that the service sends to this callback
-         * will be sent to the client that initiated the discovery request.
-         * @return True if discovery has started.  False if the media route service
-         * is unable to discover routes that satisfy the request.
-         */
-        public abstract boolean onStartDiscovery(@NonNull DiscoveryRequest req,
-                @NonNull DiscoveryCallback callback);
-
-        /**
-         * Stops discovery.
-         * <p>
-         * If {@link #onStartDiscovery} returned true, then this method will eventually
-         * be called when the framework no longer requires this discovery request
-         * to be performed.
-         * </p><p>
-         * There may still be other discovery requests in progress for other clients;
-         * they must keep working until they have each been stopped by their client.
-         * </p>
-         */
-        public abstract void onStopDiscovery();
-
-        /**
-         * Starts connecting to a route.
-         *
-         * @param req The connection request.
-         * @param callback A callback to receive events connection events related
-         * to this particular request.  The events that the service sends to this callback
-         * will be sent to the client that initiated the discovery request.
-         * @return True if the connection is in progress, or false if the client
-         * unable to connect to the requested route.
-         */
-        public abstract boolean onConnect(@NonNull ConnectionRequest req,
-                @NonNull ConnectionCallback callback);
-
-        /**
-         * Called when the client requests to disconnect from the route
-         * or abort a connection attempt in progress.
-         */
-        public abstract void onDisconnect();
-
-        /**
-         * Called when the client requests to pause streaming of content to
-         * live audio/video routes such as when it goes into the background.
-         * <p>
-         * The default implementation does nothing.
-         * </p>
-         */
-        public void onPauseStream() { }
-
-        /**
-         * Called when the application requests to resume streaming of content to
-         * live audio/video routes such as when it returns to the foreground.
-         * <p>
-         * The default implementation does nothing.
-         * </p>
-         */
-        public void onResumeStream() { }
-
-        /**
-         * Called when the client is releasing the session.
-         * <p>
-         * The framework automatically takes care of stopping discovery and
-         * terminating the connection politely before calling this method to release
-         * the session.
-         * </p><p>
-         * The default implementation does nothing.
-         * </p>
-         */
-        public void onRelease() { }
-    }
-
-    /**
-     * Provides events in response to a discovery request.
-     */
-    public final class DiscoveryCallback {
-        private final ClientRecord mRecord;
-
-        DiscoveryCallback(ClientRecord record) {
-            mRecord = record;
-        }
-
-        /**
-         * Called by the service when a destination is found that
-         * offers one or more routes that satisfy the discovery request.
-         * <p>
-         * This method should be called whenever the list of available routes
-         * at a destination changes or whenever the properties of the destination
-         * itself change.
-         * </p>
-         *
-         * @param destination The destination that was found.
-         * @param routes The list of that destination's routes that satisfy the
-         * discovery request.
-         */
-        public void onDestinationFound(final @NonNull DestinationInfo destination,
-                final @NonNull List<RouteInfo> routes) {
-            if (destination == null) {
-                throw new IllegalArgumentException("destination must not be null");
-            }
-            if (routes == null) {
-                throw new IllegalArgumentException("routes must not be null");
-            }
-            for (int i = 0; i < routes.size(); i++) {
-                if (routes.get(i).getDestination() != destination) {
-                    throw new IllegalArgumentException("routes must refer to the "
-                            + "destination");
-                }
-            }
-
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mRecord.dispatchDestinationFound(DiscoveryCallback.this,
-                            destination, routes);
-                }
-            });
-        }
-
-        /**
-         * Called by the service when a destination is no longer
-         * reachable or is no longer offering any routes that satisfy
-         * the discovery request.
-         *
-         * @param destination The destination that went away.
-         */
-        public void onDestinationLost(final @NonNull DestinationInfo destination) {
-            if (destination == null) {
-                throw new IllegalArgumentException("destination must not be null");
-            }
-
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mRecord.dispatchDestinationLost(DiscoveryCallback.this, destination);
-                }
-            });
-        }
-
-        /**
-         * Called by the service when a discovery has failed in a non-recoverable manner.
-         *
-         * @param error The error code: one of
-         * {@link MediaRouter#DISCOVERY_ERROR_UNKNOWN},
-         * {@link MediaRouter#DISCOVERY_ERROR_ABORTED},
-         * or {@link MediaRouter#DISCOVERY_ERROR_NO_CONNECTIVITY}.
-         * @param message The localized error message, or null if none.  This message
-         * may be shown to the user.
-         * @param extras Additional information about the error which a client
-         * may use, or null if none.
-         */
-        public void onDiscoveryFailed(final @DiscoveryError int error,
-                final @Nullable CharSequence message, final @Nullable Bundle extras) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mRecord.dispatchDiscoveryFailed(DiscoveryCallback.this,
-                            error, message, extras);
-                }
-            });
-        }
-    }
-
-    /**
-     * Provides events in response to a connection request.
-     */
-    public final class ConnectionCallback {
-        private final ClientRecord mRecord;
-
-        ConnectionCallback(ClientRecord record) {
-            mRecord = record;
-        }
-
-        /**
-         * Called by the service when the connection succeeds.
-         *
-         * @param connection Immutable information about the connection.
-         */
-        public void onConnected(final @NonNull ConnectionInfo connection) {
-            if (connection == null) {
-                throw new IllegalArgumentException("connection must not be null");
-            }
-
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mRecord.dispatchConnected(ConnectionCallback.this, connection);
-                }
-            });
-        }
-
-        /**
-         * Called by the service when the connection is terminated normally.
-         * <p>
-         * Abnormal termination is reported via {@link #onConnectionFailed}.
-         * </p>
-         */
-        public void onDisconnected() {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mRecord.dispatchDisconnected(ConnectionCallback.this);
-                }
-            });
-        }
-
-        /**
-         * Called by the service when a connection attempt or connection in
-         * progress has failed in a non-recoverable manner.
-         *
-         * @param error The error code: one of
-         * {@link MediaRouter#CONNECTION_ERROR_ABORTED},
-         * {@link MediaRouter#CONNECTION_ERROR_UNAUTHORIZED},
-         * {@link MediaRouter#CONNECTION_ERROR_UNREACHABLE},
-         * {@link MediaRouter#CONNECTION_ERROR_BUSY},
-         * {@link MediaRouter#CONNECTION_ERROR_TIMEOUT},
-         * {@link MediaRouter#CONNECTION_ERROR_BROKEN},
-         * or {@link MediaRouter#CONNECTION_ERROR_BARGED}.
-         * @param message The localized error message, or null if none.  This message
-         * may be shown to the user.
-         * @param extras Additional information about the error which a client
-         * may use, or null if none.
-         */
-        public void onConnectionFailed(final @ConnectionError int error,
-                final @Nullable CharSequence message, final @Nullable Bundle extras) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    mRecord.dispatchConnectionFailed(ConnectionCallback.this,
-                            error, message, extras);
-                }
-            });
-        }
-    }
-
-    /**
-     * Identifies a client of the media route service.
-     */
-    public static final class ClientInfo {
-        private final int mUid;
-        private final String mPackageName;
-
-        ClientInfo(int uid, String packageName) {
-            mUid = uid;
-            mPackageName = packageName;
-        }
-
-        /**
-         * Gets the UID of the client application.
-         */
-        public int getUid() {
-            return mUid;
-        }
-
-        /**
-         * Gets the package name of the client application.
-         */
-        public @NonNull String getPackageName() {
-            return mPackageName;
-        }
-
-        @Override
-        public @NonNull String toString() {
-            return "ClientInfo{ uid=" + mUid + ", package=" + mPackageName + " }";
-        }
-    }
-
-    private final class BinderService extends IMediaRouteService.Stub {
-        @Override
-        public void registerClient(final int clientUid, final String clientPackageName,
-                final IMediaRouteClientCallback callback) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    ClientInfo client = new ClientInfo(clientUid, clientPackageName);
-                    if (DEBUG) {
-                        Log.d(TAG, "registerClient: client=" + client);
-                    }
-
-                    ClientSession session = onCreateClientSession(client);
-                    if (session == null) {
-                        // request refused by service
-                        Log.w(TAG, "Media route service refused to create session for client: "
-                                + "client=" + client);
-                        return;
-                    }
-
-                    ClientRecord record = new ClientRecord(callback, client, session);
-                    try {
-                        callback.asBinder().linkToDeath(record, 0);
-                    } catch (RemoteException ex) {
-                        // client died prematurely
-                        Log.w(TAG, "Client died prematurely while creating session: "
-                                + "client=" + client);
-                        record.release();
-                        return;
-                    }
-
-                    mClientRecords.put(callback.asBinder(), record);
-                }
-            });
-        }
-
-        @Override
-        public void unregisterClient(IMediaRouteClientCallback callback) {
-            unregisterClient(callback, false);
-        }
-
-        void unregisterClient(final IMediaRouteClientCallback callback,
-                final boolean died) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    ClientRecord record = mClientRecords.remove(callback.asBinder());
-                    if (record == null) {
-                        return; // spurious
-                    }
-
-                    if (DEBUG) {
-                        Log.d(TAG, "unregisterClient: client=" + record.getClientInfo()
-                                + ", died=" + died);
-                    }
-
-                    record.release();
-                    callback.asBinder().unlinkToDeath(record, 0);
-                }
-            });
-        }
-
-        @Override
-        public void startDiscovery(final IMediaRouteClientCallback callback,
-                final int seq, final List<MediaRouteSelector> selectors,
-                final int flags) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    ClientRecord record = mClientRecords.get(callback.asBinder());
-                    if (record == null) {
-                        return; // spurious
-                    }
-
-                    if (DEBUG) {
-                        Log.d(TAG, "startDiscovery: client=" + record.getClientInfo()
-                                + ", seq=" + seq + ", selectors=" + selectors
-                                + ", flags=0x" + Integer.toHexString(flags));
-                    }
-                    record.startDiscovery(seq, selectors, flags);
-                }
-            });
-        }
-
-        @Override
-        public void stopDiscovery(final IMediaRouteClientCallback callback) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    ClientRecord record = mClientRecords.get(callback.asBinder());
-                    if (record == null) {
-                        return; // spurious
-                    }
-
-                    if (DEBUG) {
-                        Log.d(TAG, "stopDiscovery: client=" + record.getClientInfo());
-                    }
-                    record.stopDiscovery();
-                }
-            });
-        }
-
-        @Override
-        public void connect(final IMediaRouteClientCallback callback,
-                final int seq, final String destinationId, final String routeId,
-                final int flags, final Bundle extras) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    ClientRecord record = mClientRecords.get(callback.asBinder());
-                    if (record == null) {
-                        return; // spurious
-                    }
-
-                    if (DEBUG) {
-                        Log.d(TAG, "connect: client=" + record.getClientInfo()
-                                + ", seq=" + seq + ", destinationId=" + destinationId
-                                + ", routeId=" + routeId
-                                + ", flags=0x" + Integer.toHexString(flags)
-                                + ", extras=" + extras);
-                    }
-                    record.connect(seq, destinationId, routeId, flags, extras);
-                }
-            });
-        }
-
-        @Override
-        public void disconnect(final IMediaRouteClientCallback callback) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    ClientRecord record = mClientRecords.get(callback.asBinder());
-                    if (record == null) {
-                        return; // spurious
-                    }
-
-                    if (DEBUG) {
-                        Log.d(TAG, "disconnect: client=" + record.getClientInfo());
-                    }
-                    record.disconnect();
-                }
-            });
-        }
-
-        @Override
-        public void pauseStream(final IMediaRouteClientCallback callback) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    ClientRecord record = mClientRecords.get(callback.asBinder());
-                    if (record == null) {
-                        return; // spurious
-                    }
-
-                    if (DEBUG) {
-                        Log.d(TAG, "pauseStream: client=" + record.getClientInfo());
-                    }
-                    record.pauseStream();
-                }
-            });
-        }
-
-        @Override
-        public void resumeStream(final IMediaRouteClientCallback callback) {
-            mHandler.post(new Runnable() {
-                @Override
-                public void run() {
-                    ClientRecord record = mClientRecords.get(callback.asBinder());
-                    if (record == null) {
-                        return; // spurious
-                    }
-
-                    if (DEBUG) {
-                        Log.d(TAG, "resumeStream: client=" + record.getClientInfo());
-                    }
-                    record.resumeStream();
-                }
-            });
-        }
-    }
-
-    // Must be accessed on handler
-    private final class ClientRecord implements IBinder.DeathRecipient {
-        private final IMediaRouteClientCallback mClientCallback;
-        private final ClientInfo mClient;
-        private final ClientSession mSession;
-
-        private int mDiscoverySeq;
-        private DiscoveryRequest mDiscoveryRequest;
-        private DiscoveryCallback mDiscoveryCallback;
-        private final ArrayMap<String, DestinationRecord> mDestinations =
-                new ArrayMap<String, DestinationRecord>();
-
-        private int mConnectionSeq;
-        private ConnectionRequest mConnectionRequest;
-        private ConnectionCallback mConnectionCallback;
-        private ConnectionInfo mConnection;
-        private boolean mConnectionPaused;
-
-        public ClientRecord(IMediaRouteClientCallback callback,
-                ClientInfo client, ClientSession session) {
-            mClientCallback = callback;
-            mClient = client;
-            mSession = session;
-        }
-
-        // Invoked on binder thread unlike all other methods in this class.
-        @Override
-        public void binderDied() {
-            mService.unregisterClient(mClientCallback, true);
-        }
-
-        public ClientInfo getClientInfo() {
-            return mClient;
-        }
-
-        public void release() {
-            stopDiscovery();
-            disconnect();
-        }
-
-        public void startDiscovery(int seq, List<MediaRouteSelector> selectors,
-                int flags) {
-            stopDiscovery();
-
-            mDiscoverySeq = seq;
-            mDiscoveryRequest = new DiscoveryRequest(selectors);
-            mDiscoveryRequest.setFlags(flags);
-            mDiscoveryCallback = new DiscoveryCallback(this);
-            boolean started = mSession.onStartDiscovery(mDiscoveryRequest, mDiscoveryCallback);
-            if (!started) {
-                dispatchDiscoveryFailed(mDiscoveryCallback,
-                        MediaRouter.DISCOVERY_ERROR_ABORTED, null, null);
-                clearDiscovery();
-            }
-        }
-
-        public void stopDiscovery() {
-            if (mDiscoveryRequest != null) {
-                mSession.onStopDiscovery();
-                clearDiscovery();
-            }
-        }
-
-        private void clearDiscovery() {
-            mDestinations.clear();
-            mDiscoveryRequest = null;
-            mDiscoveryCallback = null;
-        }
-
-        public void connect(int seq, String destinationId, String routeId,
-                int flags, Bundle extras) {
-            disconnect();
-
-            mConnectionSeq = seq;
-            mConnectionCallback = new ConnectionCallback(this);
-
-            DestinationRecord destinationRecord = mDestinations.get(destinationId);
-            if (destinationRecord == null) {
-                Log.w(TAG, "Aborting connection to route since no matching destination "
-                        + "was found in the list of known destinations: "
-                        + "destinationId=" + destinationId);
-                dispatchConnectionFailed(mConnectionCallback,
-                        MediaRouter.CONNECTION_ERROR_ABORTED, null, null);
-                clearConnection();
-                return;
-            }
-
-            RouteInfo route = destinationRecord.getRoute(routeId);
-            if (route == null) {
-                Log.w(TAG, "Aborting connection to route since no matching route "
-                        + "was found in the list of known routes: "
-                        + "destination=" + destinationRecord.destination
-                        + ", routeId=" + routeId);
-                dispatchConnectionFailed(mConnectionCallback,
-                        MediaRouter.CONNECTION_ERROR_ABORTED, null, null);
-                clearConnection();
-                return;
-            }
-
-            mConnectionRequest = new ConnectionRequest(route);
-            mConnectionRequest.setFlags(flags);
-            mConnectionRequest.setExtras(extras);
-            boolean started = mSession.onConnect(mConnectionRequest, mConnectionCallback);
-            if (!started) {
-                dispatchConnectionFailed(mConnectionCallback,
-                        MediaRouter.CONNECTION_ERROR_ABORTED, null, null);
-                clearConnection();
-            }
-        }
-
-        public void disconnect() {
-            if (mConnectionRequest != null) {
-                mSession.onDisconnect();
-                clearConnection();
-            }
-        }
-
-        private void clearConnection() {
-            mConnectionRequest = null;
-            mConnectionCallback = null;
-            if (mConnection != null) {
-                mConnection.close();
-                mConnection = null;
-            }
-            mConnectionPaused = false;
-        }
-
-        public void pauseStream() {
-            if (mConnectionRequest != null && !mConnectionPaused) {
-                mConnectionPaused = true;
-                mSession.onPauseStream();
-            }
-        }
-
-        public void resumeStream() {
-            if (mConnectionRequest != null && mConnectionPaused) {
-                mConnectionPaused = false;
-                mSession.onResumeStream();
-            }
-        }
-
-        public void dispatchDestinationFound(DiscoveryCallback callback,
-                DestinationInfo destination, List<RouteInfo> routes) {
-            if (callback == mDiscoveryCallback) {
-                if (DEBUG) {
-                    Log.d(TAG, "destinationFound: destination=" + destination
-                            + ", routes=" + routes);
-                }
-                mDestinations.put(destination.getId(),
-                        new DestinationRecord(destination, routes));
-
-                ParcelableDestinationInfo pdi = new ParcelableDestinationInfo();
-                pdi.id = destination.getId();
-                pdi.name = destination.getName();
-                pdi.description = destination.getDescription();
-                pdi.iconResourceId = destination.getIconResourceId();
-                pdi.extras = destination.getExtras();
-                ArrayList<ParcelableRouteInfo> pris = new ArrayList<ParcelableRouteInfo>();
-                for (RouteInfo route : routes) {
-                    int selectorIndex = mDiscoveryRequest.getSelectors().indexOf(
-                            route.getSelector());
-                    if (selectorIndex < 0) {
-                        Log.w(TAG, "Ignoring route because the selector does not match "
-                                + "any of those that were originally supplied by the "
-                                + "client's discovery request: destination=" + destination
-                                + ", route=" + route);
-                        continue;
-                    }
-
-                    ParcelableRouteInfo pri = new ParcelableRouteInfo();
-                    pri.id = route.getId();
-                    pri.selectorIndex = selectorIndex;
-                    pri.features = route.getFeatures();
-                    pri.protocols = route.getProtocols().toArray(
-                            new String[route.getProtocols().size()]);
-                    pri.extras = route.getExtras();
-                    pris.add(pri);
-                }
-                try {
-                    mClientCallback.onDestinationFound(mDiscoverySeq, pdi,
-                            pris.toArray(new ParcelableRouteInfo[pris.size()]));
-                } catch (RemoteException ex) {
-                    // binder death handled elsewhere
-                }
-            }
-        }
-
-        public void dispatchDestinationLost(DiscoveryCallback callback,
-                DestinationInfo destination) {
-            if (callback == mDiscoveryCallback) {
-                if (DEBUG) {
-                    Log.d(TAG, "destinationLost: destination=" + destination);
-                }
-
-                if (mDestinations.get(destination.getId()).destination == destination) {
-                    mDestinations.remove(destination.getId());
-                    try {
-                        mClientCallback.onDestinationLost(mDiscoverySeq, destination.getId());
-                    } catch (RemoteException ex) {
-                        // binder death handled elsewhere
-                    }
-                }
-            }
-        }
-
-        public void dispatchDiscoveryFailed(DiscoveryCallback callback,
-                int error, CharSequence message, Bundle extras) {
-            if (callback == mDiscoveryCallback) {
-                if (DEBUG) {
-                    Log.d(TAG, "discoveryFailed: error=" + error + ", message=" + message
-                            + ", extras=" + extras);
-                }
-
-                try {
-                    mClientCallback.onDiscoveryFailed(mDiscoverySeq, error, message, extras);
-                } catch (RemoteException ex) {
-                    // binder death handled elsewhere
-                }
-            }
-        }
-
-        public void dispatchConnected(ConnectionCallback callback, ConnectionInfo connection) {
-            if (callback == mConnectionCallback) {
-                if (DEBUG) {
-                    Log.d(TAG, "connected: connection=" + connection);
-                }
-                if (mConnection == null) {
-                    mConnection = connection;
-
-                    ParcelableConnectionInfo pci = new ParcelableConnectionInfo();
-                    pci.audioAttributes = connection.getAudioAttributes();
-                    pci.presentationDisplayId = connection.getPresentationDisplay() != null ?
-                            connection.getPresentationDisplay().getDisplayId() : -1;
-                    pci.protocolBinders = new IBinder[connection.getProtocols().size()];
-                    for (int i = 0; i < pci.protocolBinders.length; i++) {
-                        pci.protocolBinders[i] = connection.getProtocolBinder(i);
-                    }
-                    pci.extras = connection.getExtras();
-                    try {
-                        mClientCallback.onConnected(mConnectionSeq, pci);
-                    } catch (RemoteException ex) {
-                        // binder death handled elsewhere
-                    }
-                } else {
-                    Log.w(TAG, "Media route service called onConnected() while already "
-                            + "connected.");
-                }
-            }
-        }
-
-        public void dispatchDisconnected(ConnectionCallback callback) {
-            if (callback == mConnectionCallback) {
-                if (DEBUG) {
-                    Log.d(TAG, "disconnected");
-                }
-
-                if (mConnection != null) {
-                    mConnection.close();
-                    mConnection = null;
-
-                    try {
-                        mClientCallback.onDisconnected(mConnectionSeq);
-                    } catch (RemoteException ex) {
-                        // binder death handled elsewhere
-                    }
-                }
-            }
-        }
-
-        public void dispatchConnectionFailed(ConnectionCallback callback,
-                int error, CharSequence message, Bundle extras) {
-            if (callback == mConnectionCallback) {
-                if (DEBUG) {
-                    Log.d(TAG, "connectionFailed: error=" + error + ", message=" + message
-                            + ", extras=" + extras);
-                }
-
-                try {
-                    mClientCallback.onConnectionFailed(mConnectionSeq, error, message, extras);
-                } catch (RemoteException ex) {
-                    // binder death handled elsewhere
-                }
-            }
-        }
-    }
-
-    private static final class DestinationRecord {
-        public final DestinationInfo destination;
-        public final List<RouteInfo> routes;
-
-        public DestinationRecord(DestinationInfo destination, List<RouteInfo> routes) {
-            this.destination = destination;
-            this.routes = routes;
-        }
-
-        public RouteInfo getRoute(String routeId) {
-            final int count = routes.size();
-            for (int i = 0; i < count; i++) {
-                RouteInfo route = routes.get(i);
-                if (route.getId().equals(routeId)) {
-                    return route;
-                }
-            }
-            return null;
-        }
-    }
-}
diff --git a/media/java/android/media/routing/MediaRouter.java b/media/java/android/media/routing/MediaRouter.java
deleted file mode 100644
index 4f6d324..0000000
--- a/media/java/android/media/routing/MediaRouter.java
+++ /dev/null
@@ -1,1886 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.media.routing;
-
-import android.annotation.DrawableRes;
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.app.Presentation;
-import android.app.Service;
-import android.content.ComponentName;
-import android.content.Context;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.pm.ServiceInfo;
-import android.graphics.drawable.Drawable;
-import android.hardware.display.DisplayManager;
-import android.media.AudioAttributes;
-import android.media.AudioManager;
-import android.media.AudioTrack;
-import android.media.VolumeProvider;
-import android.media.session.MediaController;
-import android.media.session.MediaSession;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.text.TextUtils;
-import android.util.ArrayMap;
-import android.view.Display;
-
-import java.io.Closeable;
-import java.io.IOException;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * Media router allows applications to discover, connect to, control,
- * and send content to nearby media devices known as destinations.
- * <p>
- * There are generally two participants involved in media routing: an
- * application that wants to send media content to a destination and a
- * {@link MediaRouteService media route service} that provides the
- * service of transporting that content where it needs to go on behalf of the
- * application.
- * </p><p>
- * To send media content to a destination, the application must ask the system
- * to discover available routes to destinations that provide certain capabilities,
- * establish a connection to a route, then send messages through the connection to
- * control the routing of audio and video streams, launch remote applications,
- * and invoke other functions of the destination.
- * </p><p>
- * Media router objects are thread-safe.
- * </p>
- *
- * <h3>Destinations</h3>
- * <p>
- * The media devices to which an application may send media content are referred
- * to in the API as destinations.  Each destination therefore represents a single
- * independent device such as a speaker or TV set.  Destinations are given meaningful
- * names and descriptions to help the user associate them with devices in their
- * environment.
- * </p><p>
- * Destinations may be local or remote and may be accessed through various means,
- * often wirelessly.  The user may install media route services to enable
- * media applications to connect to a variety of destinations with different
- * capabilities.
- * </p>
- *
- * <h3>Routes</h3>
- * <p>
- * Routes represent possible usages or means of reaching and interacting with
- * a destination.  Since destinations may support many different features, they may
- * each offer multiple routes for applications to choose from based on their needs.
- * For example, one route might express the ability to stream locally rendered audio
- * and video to the device; another route might express the ability to send a URL for
- * the destination to download from the network and play all by itself.
- * </p><p>
- * Routes are discovered according to the set of capabilities that
- * an application or the system is seeking to use at a particular time.  For example,
- * if an application wants to stream music to a destination then it will ask the
- * {@link MediaRouter} to find routes to destinations can stream music and ignore
- * all other destinations that cannot.
- * </p><p>
- * In general, the application will inspect the set of routes that have been
- * offered then connect to the most appropriate route for its desired purpose.
- * </p>
- *
- * <h3>Route Selection</h3>
- * <p>
- * When the user open the media route chooser activity, the system will display
- * a list of nearby media destinations which have been discovered.  After the
- * choice is made the application may connect to one of the routes offered by
- * this destination and begin communicating with the destination.
- * </p><p>
- * Destinations are located through a process called discovery.  During discovery,
- * the system will start installed {@link MediaRouteService media route services}
- * to scan the network for nearby devices that offer the kinds of capabilities that the
- * application is seeking to use.  The application specifies the capabilities it requires by
- * adding {@link MediaRouteSelector media route selectors} to the media router
- * using the {@link #addSelector} method.  Only destinations that provide routes
- * which satisfy at least one of these media route selectors will be discovered.
- * </p><p>
- * Once the user has selected a destination, the application will be given a chance
- * to choose one of the routes to which it would like to connect.  The application
- * may switch to a different route from the same destination at a later time but
- * in order to connect to a new destination, the application must once again launch
- * the media route chooser activity to ask the user to choose a destination.
- * </p>
- *
- * <h3>Route Protocols</h3>
- * <p>
- * Route protocols express capabilities offered by routes.  Each media route selector
- * must specify at least one required protocol by which the routes will be selected.
- * </p><p>
- * The framework provides several predefined <code>MediaRouteProtocols</code> which are
- * defined in the <code>android-support-media-protocols.jar</code> support library.
- * Applications must statically link this library to make use of these protocols.
- * </p><p>
- * The static library approach is used to enable ongoing extension and refinement
- * of protocols in the SDK and interoperability with the media router implementation
- * for older platform versions which is offered by the framework support library.
- * </p><p>
- * Media route services may also define custom media route protocols of their own
- * to enable applications to access specialized capabilities of certain destinations
- * assuming they have linked in the required protocol code.
- * </p><p>
- * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code> for more information.
- * </p>
- *
- * <h3>Connections</h3>
- * <p>
- * After connecting to a media route, the application can send commands to
- * the route using any of the protocols that it requested.  If the route supports live
- * audio or video streaming then the application can create an {@link AudioTrack} or
- * {@link Presentation} to route locally generated content to the destination.
- * </p>
- *
- * <h3>Delegation</h3>
- * <p>
- * The creator of the media router is responsible for establishing the policy for
- * discovering and connecting to destinations.  UI components may observe the state
- * of the media router by {@link #createDelegate creating} a {@link Delegate}.
- * </p><p>
- * The media router should also be attached to the {@link MediaSession media session}
- * that is handling media playback lifecycle.  This will allow
- * authorized {@link MediaController media controllers}, possibly running in other
- * processes, to provide UI to examine and change the media destination by
- * {@link MediaController#createMediaRouterDelegate creating} a {@link Delegate}
- * for the media router associated with the session.
- * </p>
- */
-public final class MediaRouter {
-    private final DisplayManager mDisplayManager;
-
-    private final Object mLock = new Object();
-
-    private RoutingCallback mRoutingCallback;
-    private Handler mRoutingCallbackHandler;
-
-    private boolean mReleased;
-    private int mDiscoveryState;
-    private int mConnectionState;
-    private final ArrayList<MediaRouteSelector> mSelectors =
-            new ArrayList<MediaRouteSelector>();
-    private final ArrayMap<DestinationInfo, List<RouteInfo>> mDiscoveredDestinations =
-            new ArrayMap<DestinationInfo, List<RouteInfo>>();
-    private RouteInfo mSelectedRoute;
-    private ConnectionInfo mConnection;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = { DISCOVERY_STATE_STOPPED, DISCOVERY_STATE_STARTED })
-    public @interface DiscoveryState { }
-
-    /**
-     * Discovery state: Discovery is not currently in progress.
-     */
-    public static final int DISCOVERY_STATE_STOPPED = 0;
-
-    /**
-     * Discovery state: Discovery is being performed.
-     */
-    public static final int DISCOVERY_STATE_STARTED = 1;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(flag = true, value = { DISCOVERY_FLAG_BACKGROUND })
-    public @interface DiscoveryFlags { }
-
-    /**
-     * Discovery flag: Indicates that the client has requested passive discovery in
-     * the background.  The media route service should try to use less power and rely
-     * more on its internal caches to minimize its impact.
-     */
-    public static final int DISCOVERY_FLAG_BACKGROUND = 1 << 0;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = { DISCOVERY_ERROR_UNKNOWN, DISCOVERY_ERROR_ABORTED,
-            DISCOVERY_ERROR_NO_CONNECTIVITY })
-    public @interface DiscoveryError { }
-
-    /**
-     * Discovery error: Unknown error; refer to the error message for details.
-     */
-    public static final int DISCOVERY_ERROR_UNKNOWN = 0;
-
-    /**
-     * Discovery error: The media router or media route service has decided not to
-     * handle the discovery request for some reason.
-     */
-    public static final int DISCOVERY_ERROR_ABORTED = 1;
-
-    /**
-     * Discovery error: The media route service is unable to perform discovery
-     * due to a lack of connectivity such as because the radio is disabled.
-     */
-    public static final int DISCOVERY_ERROR_NO_CONNECTIVITY = 2;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = { CONNECTION_STATE_DISCONNECTED, CONNECTION_STATE_CONNECTING,
-            CONNECTION_STATE_CONNECTED })
-    public @interface ConnectionState { }
-
-    /**
-     * Connection state: No destination has been selected.  Media content should
-     * be sent to the default output.
-     */
-    public static final int CONNECTION_STATE_DISCONNECTED = 0;
-
-    /**
-     * Connection state: The application is in the process of connecting to
-     * a route offered by the selected destination.
-     */
-    public static final int CONNECTION_STATE_CONNECTING = 1;
-
-    /**
-     * Connection state: The application has connected to a route offered by
-     * the selected destination.
-     */
-    public static final int CONNECTION_STATE_CONNECTED = 2;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(flag = true, value = { CONNECTION_FLAG_BARGE })
-    public @interface ConnectionFlags { }
-
-    /**
-     * Connection flag: Indicates that the client has requested to barge in and evict
-     * other clients that might have already connected to the destination and that
-     * would otherwise prevent this client from connecting.  When this flag is not
-     * set, the media route service should be polite and report
-     * {@link MediaRouter#CONNECTION_ERROR_BUSY} in case the destination is
-     * already occupied and cannot accept additional connections.
-     */
-    public static final int CONNECTION_FLAG_BARGE = 1 << 0;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = { CONNECTION_ERROR_UNKNOWN, CONNECTION_ERROR_ABORTED,
-            CONNECTION_ERROR_UNAUTHORIZED, CONNECTION_ERROR_UNAUTHORIZED,
-            CONNECTION_ERROR_BUSY, CONNECTION_ERROR_TIMEOUT, CONNECTION_ERROR_BROKEN })
-    public @interface ConnectionError { }
-
-    /**
-     * Connection error: Unknown error; refer to the error message for details.
-     */
-    public static final int CONNECTION_ERROR_UNKNOWN = 0;
-
-    /**
-     * Connection error: The media router or media route service has decided not to
-     * handle the connection request for some reason.
-     */
-    public static final int CONNECTION_ERROR_ABORTED = 1;
-
-    /**
-     * Connection error: The device has refused the connection from this client.
-     * This error should be avoided because the media route service should attempt
-     * to filter out devices that the client cannot access as it performs discovery
-     * on behalf of that client.
-     */
-    public static final int CONNECTION_ERROR_UNAUTHORIZED = 2;
-
-    /**
-     * Connection error: The device is unreachable over the network.
-     */
-    public static final int CONNECTION_ERROR_UNREACHABLE = 3;
-
-    /**
-     * Connection error: The device is already busy serving another client and
-     * the connection request did not ask to barge in.
-     */
-    public static final int CONNECTION_ERROR_BUSY = 4;
-
-    /**
-     * Connection error: A timeout occurred during connection.
-     */
-    public static final int CONNECTION_ERROR_TIMEOUT = 5;
-
-    /**
-     * Connection error: The connection to the device was severed unexpectedly.
-     */
-    public static final int CONNECTION_ERROR_BROKEN = 6;
-
-    /**
-     * Connection error: The connection was terminated because a different client barged
-     * in and took control of the destination.
-     */
-    public static final int CONNECTION_ERROR_BARGED = 7;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(value = { DISCONNECTION_REASON_APPLICATION_REQUEST,
-            DISCONNECTION_REASON_USER_REQUEST, DISCONNECTION_REASON_ERROR })
-    public @interface DisconnectionReason { }
-
-    /**
-     * Disconnection reason: The application requested disconnection itself.
-     */
-    public static final int DISCONNECTION_REASON_APPLICATION_REQUEST = 0;
-
-    /**
-     * Disconnection reason: The user requested disconnection.
-     */
-    public static final int DISCONNECTION_REASON_USER_REQUEST = 1;
-
-    /**
-     * Disconnection reason: An error occurred.
-     */
-    public static final int DISCONNECTION_REASON_ERROR = 2;
-
-    /** @hide */
-    @Retention(RetentionPolicy.SOURCE)
-    @IntDef(flag = true, value = { ROUTE_FEATURE_LIVE_AUDIO, ROUTE_FEATURE_LIVE_VIDEO })
-    public @interface RouteFeatures { }
-
-    /**
-     * Route feature: Live audio.
-     * <p>
-     * A route that supports live audio streams audio rendered by the application
-     * to the destination.
-     * </p><p>
-     * To take advantage of live audio routing, the application must render its
-     * media using the audio attributes specified by {@link #getPreferredAudioAttributes}.
-     * </p>
-     *
-     * @see #getPreferredAudioAttributes
-     * @see android.media.AudioAttributes
-     */
-    public static final int ROUTE_FEATURE_LIVE_AUDIO = 1 << 0;
-
-    /**
-     * Route feature: Live video.
-     * <p>
-     * A route that supports live video streams video rendered by the application
-     * to the destination.
-     * </p><p>
-     * To take advantage of live video routing, the application must render its
-     * media to a {@link android.app.Presentation presentation window} on the
-     * display specified by {@link #getPreferredPresentationDisplay}.
-     * </p>
-     *
-     * @see #getPreferredPresentationDisplay
-     * @see android.app.Presentation
-     */
-    public static final int ROUTE_FEATURE_LIVE_VIDEO = 1 << 1;
-
-    /**
-     * Creates a media router.
-     *
-     * @param context The context with which the router is associated.
-     */
-    public MediaRouter(@NonNull Context context) {
-        if (context == null) {
-            throw new IllegalArgumentException("context must not be null");
-        }
-
-        mDisplayManager = (DisplayManager)context.getSystemService(Context.DISPLAY_SERVICE);
-    }
-
-    /** @hide */
-    public IMediaRouter getBinder() {
-        // todo
-        return null;
-    }
-
-    /**
-     * Disconnects from the selected destination and releases the media router.
-     * <p>
-     * This method should be called by the application when it no longer requires
-     * the media router to ensure that all bound resources may be cleaned up.
-     * </p>
-     */
-    public void release() {
-        synchronized (mLock) {
-            mReleased = true;
-            // todo
-        }
-    }
-
-    /**
-     * Returns true if the media router has been released.
-     */
-    public boolean isReleased() {
-        synchronized (mLock) {
-            return mReleased;
-        }
-    }
-
-    /**
-     * Gets the current route discovery state.
-     *
-     * @return The current discovery state: one of {@link #DISCOVERY_STATE_STOPPED},
-     * {@link #DISCOVERY_STATE_STARTED}.
-     */
-    public @DiscoveryState int getDiscoveryState() {
-        synchronized (mLock) {
-            return mDiscoveryState;
-        }
-    }
-
-    /**
-     * Gets the current route connection state.
-     *
-     * @return The current state: one of {@link #CONNECTION_STATE_DISCONNECTED},
-     * {@link #CONNECTION_STATE_CONNECTING} or {@link #CONNECTION_STATE_CONNECTED}.
-     */
-    public @ConnectionState int getConnectionState() {
-        synchronized (mLock) {
-            return mConnectionState;
-        }
-    }
-
-    /**
-     * Creates a media router delegate through which the destination of the media
-     * router may be controlled.
-     * <p>
-     * This is the point of entry for UI code that initiates discovery and
-     * connection to routes.
-     * </p>
-     */
-    public @NonNull Delegate createDelegate() {
-        return null; // todo
-    }
-
-    /**
-     * Sets a callback to participate in route discovery, filtering, and connection
-     * establishment.
-     *
-     * @param callback The callback to set, or null if none.
-     * @param handler The handler to receive callbacks, or null to use the current thread.
-     */
-    public void setRoutingCallback(@Nullable RoutingCallback callback,
-            @Nullable Handler handler) {
-        synchronized (mLock) {
-            if (callback == null) {
-                mRoutingCallback = null;
-                mRoutingCallbackHandler = null;
-            } else {
-                mRoutingCallback = callback;
-                mRoutingCallbackHandler = handler != null ? handler : new Handler();
-            }
-        }
-    }
-
-    /**
-     * Adds a media route selector to use to find destinations that have
-     * routes with the specified capabilities during route discovery.
-     */
-    public void addSelector(@NonNull MediaRouteSelector selector) {
-        if (selector == null) {
-            throw new IllegalArgumentException("selector must not be null");
-        }
-
-        synchronized (mLock) {
-            if (!mSelectors.contains(selector)) {
-                mSelectors.add(selector);
-                // todo
-            }
-        }
-    }
-
-    /**
-     * Removes a media route selector.
-     */
-    public void removeSelector(@NonNull MediaRouteSelector selector) {
-        if (selector == null) {
-            throw new IllegalArgumentException("selector must not be null");
-        }
-
-        synchronized (mLock) {
-            if (mSelectors.remove(selector)) {
-                // todo
-            }
-        }
-    }
-
-    /**
-     * Removes all media route selectors.
-     * <p>
-     * Note that at least one selector must be added in order to perform discovery.
-     * </p>
-     */
-    public void clearSelectors() {
-        synchronized (mLock) {
-            if (!mSelectors.isEmpty()) {
-                mSelectors.clear();
-                // todo
-            }
-        }
-    }
-
-    /**
-     * Gets a list of all media route selectors to consider during discovery.
-     */
-    public @NonNull List<MediaRouteSelector> getSelectors() {
-        synchronized (mLock) {
-            return new ArrayList<MediaRouteSelector>(mSelectors);
-        }
-    }
-
-    /**
-     * Gets the connection to the currently selected route.
-     *
-     * @return The connection to the currently selected route, or null if not connected.
-     */
-    public @NonNull ConnectionInfo getConnection() {
-        synchronized (mLock) {
-            return mConnection;
-        }
-    }
-
-    /**
-     * Gets the list of discovered destinations.
-     * <p>
-     * This list is only valid while discovery is running and is null otherwise.
-     * </p>
-     *
-     * @return The list of discovered destinations, or null if discovery is not running.
-     */
-    public @NonNull List<DestinationInfo> getDiscoveredDestinations() {
-        synchronized (mLock) {
-            if (mDiscoveryState == DISCOVERY_STATE_STARTED) {
-                return new ArrayList<DestinationInfo>(mDiscoveredDestinations.keySet());
-            }
-            return null;
-        }
-    }
-
-    /**
-     * Gets the list of discovered routes for a particular destination.
-     * <p>
-     * This list is only valid while discovery is running and is null otherwise.
-     * </p>
-     *
-     * @param destination The destination for which to get the list of discovered routes.
-     * @return The list of discovered routes for the destination, or null if discovery
-     * is not running.
-     */
-    public @NonNull List<RouteInfo> getDiscoveredRoutes(@NonNull DestinationInfo destination) {
-        if (destination == null) {
-            throw new IllegalArgumentException("destination must not be null");
-        }
-        synchronized (mLock) {
-            if (mDiscoveryState == DISCOVERY_STATE_STARTED) {
-                List<RouteInfo> routes = mDiscoveredDestinations.get(destination);
-                if (routes != null) {
-                    return new ArrayList<RouteInfo>(routes);
-                }
-            }
-            return null;
-        }
-    }
-
-    /**
-     * Gets the destination that has been selected.
-     *
-     * @return The selected destination, or null if disconnected.
-     */
-    public @Nullable DestinationInfo getSelectedDestination() {
-        synchronized (mLock) {
-            return mSelectedRoute != null ? mSelectedRoute.getDestination() : null;
-        }
-    }
-
-    /**
-     * Gets the route that has been selected.
-     *
-     * @return The selected destination, or null if disconnected.
-     */
-    public @Nullable RouteInfo getSelectedRoute() {
-        synchronized (mLock) {
-            return mSelectedRoute;
-        }
-    }
-
-    /**
-     * Gets the preferred audio attributes that should be used to stream live audio content
-     * based on the connected route.
-     * <p>
-     * Use an {@link AudioTrack} to send audio content to the destination with these
-     * audio attributes.
-     * </p><p>
-     * The preferred audio attributes may change when a connection is established but it
-     * will remain constant until disconnected.
-     * </p>
-     *
-     * @return The preferred audio attributes to use.  When connected, returns the
-     * route's audio attributes or null if it does not support live audio streaming.
-     * Otherwise returns audio attributes associated with {@link AudioAttributes#USAGE_MEDIA}.
-     */
-    public @Nullable AudioAttributes getPreferredAudioAttributes() {
-        synchronized (mLock) {
-            if (mConnection != null) {
-                return mConnection.getAudioAttributes();
-            }
-            return new AudioAttributes.Builder()
-                    .setLegacyStreamType(AudioManager.STREAM_MUSIC)
-                    .build();
-        }
-    }
-
-    /**
-     * Gets the preferred presentation display that should be used to stream live video content
-     * based on the connected route.
-     * <p>
-     * Use a {@link Presentation} to send video content to the destination with this display.
-     * </p><p>
-     * The preferred presentation display may change when a connection is established but it
-     * will remain constant until disconnected.
-     * </p>
-     *
-     * @return The preferred presentation display to use.  When connected, returns
-     * the route's presentation display or null if it does not support live video
-     * streaming.  Otherwise returns the first available
-     * {@link DisplayManager#DISPLAY_CATEGORY_PRESENTATION presentation display},
-     * such as a mirrored wireless or HDMI display or null if none.
-     */
-    public @Nullable Display getPreferredPresentationDisplay() {
-        synchronized (mLock) {
-            if (mConnection != null) {
-                return mConnection.getPresentationDisplay();
-            }
-            Display[] displays = mDisplayManager.getDisplays(
-                    DisplayManager.DISPLAY_CATEGORY_PRESENTATION);
-            return displays.length != 0 ? displays[0] : null;
-        }
-    }
-
-    /**
-     * Gets the preferred volume provider that should be used to control the volume
-     * of content rendered on the currently selected route.
-     * <p>
-     * The preferred volume provider may change when a connection is established but it
-     * will remain the same until disconnected.
-     * </p>
-     *
-     * @return The preferred volume provider to use, or null if the currently
-     * selected route does not support remote volume adjustment or if the connection
-     * is not yet established.  If no route is selected, returns null to indicate
-     * that system volume control should be used.
-     */
-    public @Nullable VolumeProvider getPreferredVolumeProvider() {
-        synchronized (mLock) {
-            if (mConnection != null) {
-                return mConnection.getVolumeProvider();
-            }
-            return null;
-        }
-    }
-
-    /**
-     * Requests to pause streaming of live audio or video routes.
-     * Should be called when the application is going into the background and is
-     * no longer rendering content locally.
-     * <p>
-     * This method does nothing unless a connection has been established.
-     * </p>
-     */
-    public void pauseStream() {
-        // todo
-    }
-
-    /**
-     * Requests to resume streaming of live audio or video routes.
-     * May be called when the application is returning to the foreground and is
-     * about to resume rendering content locally.
-     * <p>
-     * This method does nothing unless a connection has been established.
-     * </p>
-     */
-    public void resumeStream() {
-        // todo
-    }
-
-    /**
-     * This class is used by UI components to let the user discover and
-     * select a destination to which the media router should connect.
-     * <p>
-     * This API has somewhat more limited functionality than the {@link MediaRouter}
-     * itself because it is designed to allow applications to control
-     * the destination of media router instances that belong to other processes.
-     * </p><p>
-     * To control the destination of your own media router, call
-     * {@link #createDelegate} to obtain a local delegate object.
-     * </p><p>
-     * To control the destination of a media router that belongs to another process,
-     * first obtain a {@link MediaController} that is associated with the media playback
-     * that is occurring in that process, then call
-     * {@link MediaController#createMediaRouterDelegate} to obtain an instance of
-     * its destination controls.  Note that special permissions may be required to
-     * obtain the {@link MediaController} instance in the first place.
-     * </p>
-     */
-    public static final class Delegate {
-        /**
-         * Returns true if the media router has been released.
-         */
-        public boolean isReleased() {
-            // todo
-            return false;
-        }
-
-        /**
-         * Gets the current route discovery state.
-         *
-         * @return The current discovery state: one of {@link #DISCOVERY_STATE_STOPPED},
-         * {@link #DISCOVERY_STATE_STARTED}.
-         */
-        public @DiscoveryState int getDiscoveryState() {
-            // todo
-            return -1;
-        }
-
-        /**
-         * Gets the current route connection state.
-         *
-         * @return The current state: one of {@link #CONNECTION_STATE_DISCONNECTED},
-         * {@link #CONNECTION_STATE_CONNECTING} or {@link #CONNECTION_STATE_CONNECTED}.
-         */
-        public @ConnectionState int getConnectionState() {
-            // todo
-            return -1;
-        }
-
-        /**
-         * Gets the currently selected destination.
-         *
-         * @return The destination information, or null if none.
-         */
-        public @Nullable DestinationInfo getSelectedDestination() {
-            return null;
-        }
-
-        /**
-         * Gets the list of discovered destinations.
-         * <p>
-         * This list is only valid while discovery is running and is null otherwise.
-         * </p>
-         *
-         * @return The list of discovered destinations, or null if discovery is not running.
-         */
-        public @NonNull List<DestinationInfo> getDiscoveredDestinations() {
-            return null;
-        }
-
-        /**
-         * Adds a callback to receive state changes.
-         *
-         * @param callback The callback to set, or null if none.
-         * @param handler The handler to receive callbacks, or null to use the current thread.
-         */
-        public void addStateCallback(@Nullable StateCallback callback,
-                @Nullable Handler handler) {
-            if (callback == null) {
-                throw new IllegalArgumentException("callback must not be null");
-            }
-            if (handler == null) {
-                handler = new Handler();
-            }
-            // todo
-        }
-
-        /**
-         * Removes a callback for state changes.
-         *
-         * @param callback The callback to set, or null if none.
-         */
-        public void removeStateCallback(@Nullable StateCallback callback) {
-            // todo
-        }
-
-        /**
-         * Starts performing discovery.
-         * <p>
-         * Performing discovery is expensive.  Make sure to call {@link #stopDiscovery}
-         * as soon as possible once a new destination has been selected to allow the system
-         * to stop services associated with discovery.
-         * </p>
-         *
-         * @param flags The discovery flags, such as {@link MediaRouter#DISCOVERY_FLAG_BACKGROUND}.
-         */
-        public void startDiscovery(@DiscoveryFlags int flags) {
-            // todo
-        }
-
-        /**
-         * Stops performing discovery.
-         */
-        public void stopDiscovery() {
-            // todo
-        }
-
-        /**
-         * Connects to a destination during route discovery.
-         * <p>
-         * This method may only be called while route discovery is active and the
-         * destination appears in the
-         * {@link #getDiscoveredDestinations list of discovered destinations}.
-         * If the media router is already connected to a route then it will first disconnect
-         * from the current route then connect to the new route.
-         * </p>
-         *
-         * @param destination The destination to which the media router should connect.
-         * @param flags The connection flags, such as {@link MediaRouter#CONNECTION_FLAG_BARGE}.
-         */
-        public void connect(@NonNull DestinationInfo destination, @DiscoveryFlags int flags) {
-            // todo
-        }
-
-        /**
-         * Disconnects from the currently selected destination.
-         * <p>
-         * Does nothing if not currently connected.
-         * </p>
-         *
-         * @param reason The reason for the disconnection: one of
-         * {@link #DISCONNECTION_REASON_APPLICATION_REQUEST},
-         * {@link #DISCONNECTION_REASON_USER_REQUEST}, or {@link #DISCONNECTION_REASON_ERROR}.
-         */
-        public void disconnect(@DisconnectionReason int reason) {
-            // todo
-        }
-    }
-
-    /**
-     * Describes immutable properties of a connection to a route.
-     */
-    public static final class ConnectionInfo {
-        private final RouteInfo mRoute;
-        private final AudioAttributes mAudioAttributes;
-        private final Display mPresentationDisplay;
-        private final VolumeProvider mVolumeProvider;
-        private final IBinder[] mProtocolBinders;
-        private final Object[] mProtocolInstances;
-        private final Bundle mExtras;
-        private final ArrayList<Closeable> mCloseables;
-
-        private static final Class<?>[] MEDIA_ROUTE_PROTOCOL_CTOR_PARAMETERS =
-                new Class<?>[] { IBinder.class };
-
-        ConnectionInfo(RouteInfo route,
-                AudioAttributes audioAttributes, Display display,
-                VolumeProvider volumeProvider, IBinder[] protocolBinders,
-                Bundle extras, ArrayList<Closeable> closeables) {
-            mRoute = route;
-            mAudioAttributes = audioAttributes;
-            mPresentationDisplay = display;
-            mVolumeProvider = volumeProvider;
-            mProtocolBinders = protocolBinders;
-            mProtocolInstances = new Object[mProtocolBinders.length];
-            mExtras = extras;
-            mCloseables = closeables;
-        }
-
-        /**
-         * Gets the route that is connected.
-         */
-        public @NonNull RouteInfo getRoute() {
-            return mRoute;
-        }
-
-        /**
-         * Gets the audio attributes which the client should use to stream audio
-         * to the destination, or null if the route does not support live audio streaming.
-         */
-        public @Nullable AudioAttributes getAudioAttributes() {
-            return mAudioAttributes;
-        }
-
-        /**
-         * Gets the display which the client should use to stream video to the
-         * destination using a {@link Presentation}, or null if the route does not
-         * support live video streaming.
-         */
-        public @Nullable Display getPresentationDisplay() {
-            return mPresentationDisplay;
-        }
-
-        /**
-         * Gets the route's volume provider, or null if none.
-         */
-        public @Nullable VolumeProvider getVolumeProvider() {
-            return mVolumeProvider;
-        }
-
-        /**
-         * Gets the set of supported route features.
-         */
-        public @RouteFeatures int getFeatures() {
-            return mRoute.getFeatures();
-        }
-
-        /**
-         * Gets the list of supported route protocols.
-         * <p>
-         * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
-         * for more information.
-         * </p>
-         */
-        public @NonNull List<String> getProtocols() {
-            return mRoute.getProtocols();
-        }
-
-        /**
-         * Gets an instance of a route protocol object that wraps the protocol binder
-         * and provides easy access to the protocol's functionality.
-         * <p>
-         * This is a convenience method which invokes {@link #getProtocolBinder(String)}
-         * using the name of the provided class then passes the resulting {@link IBinder}
-         * to a single-argument constructor of that class.
-         * </p><p>
-         * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
-         * for more information.
-         * </p>
-         */
-        @SuppressWarnings("unchecked")
-        public @Nullable <T> T getProtocolObject(Class<T> clazz) {
-            int index = getProtocols().indexOf(clazz.getName());
-            if (index < 0) {
-                return null;
-            }
-            if (mProtocolInstances[index] == null && mProtocolBinders[index] != null) {
-                final Constructor<T> ctor;
-                try {
-                    ctor = clazz.getConstructor(MEDIA_ROUTE_PROTOCOL_CTOR_PARAMETERS);
-                } catch (NoSuchMethodException ex) {
-                    throw new RuntimeException("Could not find public constructor "
-                            + "with IBinder argument in protocol class: " + clazz.getName(), ex);
-                }
-                try {
-                    mProtocolInstances[index] = ctor.newInstance(mProtocolBinders[index]);
-                } catch (InstantiationException | IllegalAccessException
-                        | InvocationTargetException ex) {
-                    throw new RuntimeException("Could create instance of protocol class: "
-                            + clazz.getName(), ex);
-                }
-            }
-            return (T)mProtocolInstances[index];
-        }
-
-        /**
-         * Gets the {@link IBinder} that provides access to the specified route protocol
-         * or null if the protocol is not supported.
-         * <p>
-         * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
-         * for more information.
-         * </p>
-         */
-        public @Nullable IBinder getProtocolBinder(@NonNull String name) {
-            int index = getProtocols().indexOf(name);
-            return index >= 0 ? mProtocolBinders[index] : null;
-        }
-
-        /**
-         * Gets the {@link IBinder} that provides access to the specified route protocol
-         * at the given index in the protocol list or null if the protocol is not supported.
-         * <p>
-         * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
-         * for more information.
-         * </p>
-         */
-        public @Nullable IBinder getProtocolBinder(int index) {
-            return mProtocolBinders[index];
-        }
-
-        /**
-         * Gets optional extra media route service or protocol specific information about
-         * the connection.  Use the service or protocol name as the prefix for
-         * any extras to avoid namespace collisions.
-         */
-        public @Nullable Bundle getExtras() {
-            return mExtras;
-        }
-
-        /**
-         * Closes all closeables associated with the connection when the connection
-         * is being torn down.
-         */
-        void close() {
-            final int count = mCloseables.size();
-            for (int i = 0; i < count; i++) {
-                try {
-                    mCloseables.get(i).close();
-                } catch (IOException ex) {
-                }
-            }
-        }
-
-        @Override
-        public @NonNull String toString() {
-            return "ConnectionInfo{ route=" + mRoute
-                    + ", audioAttributes=" + mAudioAttributes
-                    + ", presentationDisplay=" + mPresentationDisplay
-                    + ", volumeProvider=" + mVolumeProvider
-                    + ", protocolBinders=" + mProtocolBinders + " }";
-        }
-
-        /**
-         * Builds {@link ConnectionInfo} objects.
-         */
-        public static final class Builder {
-            private final RouteInfo mRoute;
-            private AudioAttributes mAudioAttributes;
-            private Display mPresentationDisplay;
-            private VolumeProvider mVolumeProvider;
-            private final IBinder[] mProtocols;
-            private Bundle mExtras;
-            private final ArrayList<Closeable> mCloseables = new ArrayList<Closeable>();
-
-            /**
-             * Creates a builder for connection information.
-             *
-             * @param route The route that is connected.
-             */
-            public Builder(@NonNull RouteInfo route) {
-                if (route == null) {
-                    throw new IllegalArgumentException("route");
-                }
-                mRoute = route;
-                mProtocols = new IBinder[route.getProtocols().size()];
-            }
-
-            /**
-             * Sets the audio attributes which the client should use to stream audio
-             * to the destination, or null if the route does not support live audio streaming.
-             */
-            public @NonNull Builder setAudioAttributes(
-                    @Nullable AudioAttributes audioAttributes) {
-                mAudioAttributes = audioAttributes;
-                return this;
-            }
-
-            /**
-             * Sets the display which the client should use to stream video to the
-             * destination using a {@link Presentation}, or null if the route does not
-             * support live video streaming.
-             */
-            public @NonNull Builder setPresentationDisplay(@Nullable Display display) {
-                mPresentationDisplay = display;
-                return this;
-            }
-
-            /**
-             * Sets the route's volume provider, or null if none.
-             */
-            public @NonNull Builder setVolumeProvider(@Nullable VolumeProvider provider) {
-                mVolumeProvider = provider;
-                return this;
-            }
-
-            /**
-             * Sets the binder stub of a supported route protocol using
-             * the protocol's fully qualified class name.  The protocol must be one
-             * of those that was indicated as being supported by the route.
-             * <p>
-             * If the stub implements {@link Closeable} then it will automatically
-             * be closed when the client disconnects from the route.
-             * </p><p>
-             * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
-             * for more information.
-             * </p>
-             */
-            public @NonNull Builder setProtocolStub(@NonNull Class<?> clazz,
-                    @NonNull IInterface stub) {
-                if (clazz == null) {
-                    throw new IllegalArgumentException("clazz must not be null");
-                }
-                if (stub == null) {
-                    throw new IllegalArgumentException("stub must not be null");
-                }
-                if (stub instanceof Closeable) {
-                    mCloseables.add((Closeable)stub);
-                }
-                return setProtocolBinder(clazz.getName(), stub.asBinder());
-            }
-
-            /**
-             * Sets the binder interface of a supported route protocol by name.
-             * The protocol must be one of those that was indicated as being supported
-             * by the route.
-             * <p>
-             * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
-             * for more information.
-             * </p>
-             */
-            public @NonNull Builder setProtocolBinder(@NonNull String name,
-                    @NonNull IBinder binder) {
-                if (TextUtils.isEmpty(name)) {
-                    throw new IllegalArgumentException("name must not be null or empty");
-                }
-                if (binder == null) {
-                    throw new IllegalArgumentException("binder must not be null");
-                }
-                int index = mRoute.getProtocols().indexOf(name);
-                if (index < 0) {
-                    throw new IllegalArgumentException("name must specify a protocol that "
-                            + "the route actually declared that it supports: "
-                            + "name=" + name + ", protocols=" + mRoute.getProtocols());
-                }
-                mProtocols[index] = binder;
-                return this;
-            }
-
-            /**
-             * Sets optional extra media route service or protocol specific information about
-             * the connection.  Use the service or protocol name as the prefix for
-             * any extras to avoid namespace collisions.
-             */
-            public @NonNull Builder setExtras(@Nullable Bundle extras) {
-                mExtras = extras;
-                return this;
-            }
-
-            /**
-             * Builds the {@link ConnectionInfo} object.
-             */
-            public @NonNull ConnectionInfo build() {
-                return new ConnectionInfo(mRoute,
-                        mAudioAttributes, mPresentationDisplay,
-                        mVolumeProvider, mProtocols, mExtras, mCloseables);
-            }
-        }
-    }
-
-    /**
-     * Describes one particular way of routing media content to a destination
-     * according to the capabilities specified by a media route selector on behalf
-     * of an application.
-     */
-    public static final class RouteInfo {
-        private final String mId;
-        private final DestinationInfo mDestination;
-        private final MediaRouteSelector mSelector;
-        private final int mFeatures;
-        private final ArrayList<String> mProtocols;
-        private final Bundle mExtras;
-
-        RouteInfo(String id, DestinationInfo destination, MediaRouteSelector selector,
-                int features, ArrayList<String> protocols, Bundle extras) {
-            mId = id;
-            mDestination = destination;
-            mSelector = selector;
-            mFeatures = features;
-            mProtocols = protocols;
-            mExtras = extras;
-        }
-
-        /**
-         * Gets the route's stable identifier.
-         * <p>
-         * The id is intended to uniquely identify the route among all routes that
-         * are offered by a particular destination in such a way that the client can
-         * refer to it at a later time.
-         * </p>
-         */
-        public @NonNull String getId() {
-            return mId;
-        }
-
-        /**
-         * Gets the destination that is offering this route.
-         */
-        public @NonNull DestinationInfo getDestination() {
-            return mDestination;
-        }
-
-        /**
-         * Gets the media route selector provided by the client for which this
-         * route was created.
-         * <p>
-         * It is implied that this route supports all of the required capabilities
-         * that were expressed in the selector.
-         * </p>
-         */
-        public @NonNull MediaRouteSelector getSelector() {
-            return mSelector;
-        }
-
-        /**
-         * Gets the set of supported route features.
-         */
-        public @RouteFeatures int getFeatures() {
-            return mFeatures;
-        }
-
-        /**
-         * Gets the list of supported route protocols.
-         * <p>
-         * Refer to <code>android.support.media.protocols.MediaRouteProtocol</code>
-         * for more information.
-         * </p>
-         */
-        public @NonNull List<String> getProtocols() {
-            return mProtocols;
-        }
-
-        /**
-         * Gets optional extra information about the route, or null if none.
-         */
-        public @Nullable Bundle getExtras() {
-            return mExtras;
-        }
-
-        @Override
-        public @NonNull String toString() {
-            return "RouteInfo{ id=" + mId + ", destination=" + mDestination
-                    + ", features=0x" + Integer.toHexString(mFeatures)
-                    + ", selector=" + mSelector + ", protocols=" + mProtocols
-                    + ", extras=" + mExtras + " }";
-        }
-
-        /**
-         * Builds {@link RouteInfo} objects.
-         */
-        public static final class Builder {
-            private final DestinationInfo mDestination;
-            private final String mId;
-            private final MediaRouteSelector mSelector;
-            private int mFeatures;
-            private final ArrayList<String> mProtocols = new ArrayList<String>();
-            private Bundle mExtras;
-
-            /**
-             * Creates a builder for route information.
-             *
-             * @param id The route's stable identifier.
-             * @param destination The destination of this route.
-             * @param selector The media route selector provided by the client for which
-             * this route was created.  This must be one of the selectors that was
-             * included in the discovery request.
-             */
-            public Builder(@NonNull String id, @NonNull DestinationInfo destination,
-                    @NonNull MediaRouteSelector selector) {
-                if (TextUtils.isEmpty(id)) {
-                    throw new IllegalArgumentException("id must not be null or empty");
-                }
-                if (destination == null) {
-                    throw new IllegalArgumentException("destination must not be null");
-                }
-                if (selector == null) {
-                    throw new IllegalArgumentException("selector must not be null");
-                }
-                mDestination = destination;
-                mId = id;
-                mSelector = selector;
-            }
-
-            /**
-             * Sets the set of supported route features.
-             */
-            public @NonNull Builder setFeatures(@RouteFeatures int features) {
-                mFeatures = features;
-                return this;
-            }
-
-            /**
-             * Adds a supported route protocol using its fully qualified class name.
-             * <p>
-             * If the protocol was not requested by the client in its selector
-             * then it will be silently discarded.
-             * </p>
-             */
-            public @NonNull <T extends IInterface> Builder addProtocol(@NonNull Class<T> clazz) {
-                if (clazz == null) {
-                    throw new IllegalArgumentException("clazz must not be null");
-                }
-                return addProtocol(clazz.getName());
-            }
-
-            /**
-             * Adds a supported route protocol by name.
-             * <p>
-             * If the protocol was not requested by the client in its selector
-             * then it will be silently discarded.
-             * </p>
-             */
-            public @NonNull Builder addProtocol(@NonNull String name) {
-                if (TextUtils.isEmpty(name)) {
-                    throw new IllegalArgumentException("name must not be null");
-                }
-                if (mSelector.containsProtocol(name)) {
-                    mProtocols.add(name);
-                }
-                return this;
-            }
-
-            /**
-             * Sets optional extra information about the route, or null if none.
-             */
-            public @NonNull Builder setExtras(@Nullable Bundle extras) {
-                mExtras = extras;
-                return this;
-            }
-
-            /**
-             * Builds the {@link RouteInfo} object.
-             * <p>
-             * Ensures that all required protocols have been supplied.
-             * </p>
-             */
-            public @NonNull RouteInfo build() {
-                int missingFeatures = mSelector.getRequiredFeatures() & ~mFeatures;
-                if (missingFeatures != 0) {
-                    throw new IllegalStateException("The media route selector "
-                            + "specified required features which this route does "
-                            + "not appear to support so it should not have been published: "
-                            + "missing 0x" + Integer.toHexString(missingFeatures));
-                }
-                for (String protocol : mSelector.getRequiredProtocols()) {
-                    if (!mProtocols.contains(protocol)) {
-                        throw new IllegalStateException("The media route selector "
-                                + "specified required protocols which this route "
-                                + "does not appear to support so it should not have "
-                                + "been published: missing " + protocol);
-                    }
-                }
-                return new RouteInfo(mId, mDestination, mSelector,
-                        mFeatures, mProtocols, mExtras);
-            }
-        }
-    }
-
-    /**
-     * Describes a destination for media content such as a device,
-     * an individual port on a device, or a group of devices.
-     */
-    public static final class DestinationInfo {
-        private final String mId;
-        private final ServiceMetadata mService;
-        private final CharSequence mName;
-        private final CharSequence mDescription;
-        private final int mIconResourceId;
-        private final Bundle mExtras;
-
-        DestinationInfo(String id, ServiceMetadata service,
-                CharSequence name, CharSequence description,
-                int iconResourceId, Bundle extras) {
-            mId = id;
-            mService = service;
-            mName = name;
-            mDescription = description;
-            mIconResourceId = iconResourceId;
-            mExtras = extras;
-        }
-
-        /**
-         * Gets the destination's stable identifier.
-         * <p>
-         * The id is intended to uniquely identify the destination among all destinations
-         * provided by the media route service in such a way that the client can
-         * refer to it at a later time.  Ideally, the id should be resilient to
-         * user-initiated actions such as changes to the name or description
-         * of the destination.
-         * </p>
-         */
-        public @NonNull String getId() {
-            return mId;
-        }
-
-        /**
-         * Gets metadata about the service that is providing access to this destination.
-         */
-        public @NonNull ServiceMetadata getServiceMetadata() {
-            return mService;
-        }
-
-        /**
-         * Gets the destination's name for display to the user.
-         */
-        public @NonNull CharSequence getName() {
-            return mName;
-        }
-
-        /**
-         * Gets the destination's description for display to the user, or null if none.
-         */
-        public @Nullable CharSequence getDescription() {
-            return mDescription;
-        }
-
-        /**
-         * Gets an icon resource from the service's package which is used
-         * to identify the destination, or -1 if none.
-         */
-        public @DrawableRes int getIconResourceId() {
-            return mIconResourceId;
-        }
-
-        /**
-         * Loads the icon drawable, or null if none.
-         */
-        public @Nullable Drawable loadIcon(@NonNull PackageManager pm) {
-            return mIconResourceId >= 0 ? mService.getDrawable(pm, mIconResourceId) : null;
-        }
-
-        /**
-         * Gets optional extra information about the destination, or null if none.
-         */
-        public @Nullable Bundle getExtras() {
-            return mExtras;
-        }
-
-        @Override
-        public @NonNull String toString() {
-            return "DestinationInfo{ id=" + mId + ", service=" + mService + ", name=" + mName
-                    + ", description=" + mDescription + ", iconResourceId=" + mIconResourceId
-                    + ", extras=" + mExtras + " }";
-        }
-
-        /**
-         * Builds {@link DestinationInfo} objects.
-         */
-        public static final class Builder {
-            private final String mId;
-            private final ServiceMetadata mService;
-            private final CharSequence mName;
-            private CharSequence mDescription;
-            private int mIconResourceId = -1;
-            private Bundle mExtras;
-
-            /**
-             * Creates a builder for destination information.
-             *
-             * @param id The destination's stable identifier.
-             * @param service Metatada about the service that is providing access to
-             * this destination.
-             * @param name The destination's name for display to the user.
-             */
-            public Builder(@NonNull String id, @NonNull ServiceMetadata service,
-                    @NonNull CharSequence name) {
-                if (TextUtils.isEmpty(id)) {
-                    throw new IllegalArgumentException("id must not be null or empty");
-                }
-                if (service == null) {
-                    throw new IllegalArgumentException("service must not be null");
-                }
-                if (TextUtils.isEmpty(name)) {
-                    throw new IllegalArgumentException("name must not be null or empty");
-                }
-                mId = id;
-                mService = service;
-                mName = name;
-            }
-
-            /**
-             * Sets the destination's description for display to the user, or null if none.
-             */
-            public @NonNull Builder setDescription(@Nullable CharSequence description) {
-                mDescription = description;
-                return this;
-            }
-
-            /**
-             * Sets an icon resource from this package used to identify the destination,
-             * or -1 if none.
-             */
-            public @NonNull Builder setIconResourceId(@DrawableRes int resid) {
-                mIconResourceId = resid;
-                return this;
-            }
-
-            /**
-             * Gets optional extra information about the destination, or null if none.
-             */
-            public @NonNull Builder setExtras(@Nullable Bundle extras) {
-                mExtras = extras;
-                return this;
-            }
-
-            /**
-             * Builds the {@link DestinationInfo} object.
-             */
-            public @NonNull DestinationInfo build() {
-                return new DestinationInfo(mId, mService, mName, mDescription,
-                        mIconResourceId, mExtras);
-            }
-        }
-    }
-
-    /**
-     * Describes metadata about a {@link MediaRouteService} which is providing
-     * access to certain kinds of destinations.
-     */
-    public static final class ServiceMetadata {
-        private final ServiceInfo mService;
-        private CharSequence mLabel;
-        private Drawable mIcon;
-
-        ServiceMetadata(Service service) throws NameNotFoundException {
-            mService = service.getPackageManager().getServiceInfo(
-                    new ComponentName(service, service.getClass()),
-                    PackageManager.GET_META_DATA);
-        }
-
-        ServiceMetadata(ServiceInfo service) {
-            mService = service;
-        }
-
-        /**
-         * Gets the service's component information including it name, label and icon.
-         */
-        public @NonNull ServiceInfo getService() {
-            return mService;
-        }
-
-        /**
-         * Gets the service's component name.
-         */
-        public @NonNull ComponentName getComponentName() {
-            return new ComponentName(mService.packageName, mService.name);
-        }
-
-        /**
-         * Gets the service's package name.
-         */
-        public @NonNull String getPackageName() {
-            return mService.packageName;
-        }
-
-        /**
-         * Gets the service's name for display to the user, or null if none.
-         */
-        public @NonNull CharSequence getLabel(@NonNull PackageManager pm) {
-            if (mLabel == null) {
-                mLabel = mService.loadLabel(pm);
-            }
-            return mLabel;
-        }
-
-        /**
-         * Gets the icon drawable, or null if none.
-         */
-        public @Nullable Drawable getIcon(@NonNull PackageManager pm) {
-            if (mIcon == null) {
-                mIcon = mService.loadIcon(pm);
-            }
-            return mIcon;
-        }
-
-        // TODO: add service metadata
-
-        Drawable getDrawable(PackageManager pm, int resid) {
-            return pm.getDrawable(getPackageName(), resid, mService.applicationInfo);
-        }
-
-        @Override
-        public @NonNull String toString() {
-            return "ServiceInfo{ service=" + getComponentName().toShortString() + " }";
-        }
-    }
-
-    /**
-     * Describes a request to discover routes on behalf of an application.
-     */
-    public static final class DiscoveryRequest {
-        private final ArrayList<MediaRouteSelector> mSelectors =
-                new ArrayList<MediaRouteSelector>();
-        private int mFlags;
-
-        DiscoveryRequest(@NonNull List<MediaRouteSelector> selectors) {
-            setSelectors(selectors);
-        }
-
-        /**
-         * Sets the list of media route selectors to consider during discovery.
-         */
-        public void setSelectors(@NonNull List<MediaRouteSelector> selectors) {
-            if (selectors == null) {
-                throw new IllegalArgumentException("selectors");
-            }
-            mSelectors.clear();
-            mSelectors.addAll(selectors);
-        }
-
-        /**
-         * Gets the list of media route selectors to consider during discovery.
-         */
-        public @NonNull List<MediaRouteSelector> getSelectors() {
-            return mSelectors;
-        }
-
-        /**
-         * Gets discovery flags, such as {@link MediaRouter#DISCOVERY_FLAG_BACKGROUND}.
-         */
-        public @DiscoveryFlags int getFlags() {
-            return mFlags;
-        }
-
-        /**
-         * Sets discovery flags, such as {@link MediaRouter#DISCOVERY_FLAG_BACKGROUND}.
-         */
-        public void setFlags(@DiscoveryFlags int flags) {
-            mFlags = flags;
-        }
-
-        @Override
-        public @NonNull String toString() {
-            return "DiscoveryRequest{ selectors=" + mSelectors
-                    + ", flags=0x" + Integer.toHexString(mFlags)
-                    + " }";
-        }
-    }
-
-    /**
-     * Describes a request to connect to a previously discovered route on
-     * behalf of an application.
-     */
-    public static final class ConnectionRequest {
-        private RouteInfo mRoute;
-        private int mFlags;
-        private Bundle mExtras;
-
-        ConnectionRequest(@NonNull RouteInfo route) {
-            setRoute(route);
-        }
-
-        /**
-         * Gets the route to which to connect.
-         */
-        public @NonNull RouteInfo getRoute() {
-            return mRoute;
-        }
-
-        /**
-         * Sets the route to which to connect.
-         */
-        public void setRoute(@NonNull RouteInfo route) {
-            if (route == null) {
-                throw new IllegalArgumentException("route must not be null");
-            }
-            mRoute = route;
-        }
-
-        /**
-         * Gets connection flags, such as {@link MediaRouter#CONNECTION_FLAG_BARGE}.
-         */
-        public @ConnectionFlags int getFlags() {
-            return mFlags;
-        }
-
-        /**
-         * Sets connection flags, such as {@link MediaRouter#CONNECTION_FLAG_BARGE}.
-         */
-        public void setFlags(@ConnectionFlags int flags) {
-            mFlags = flags;
-        }
-
-        /**
-         * Gets optional extras supplied by the application as part of the call to
-         * connect, or null if none.  The media route service may use this
-         * information to configure the route during connection.
-         */
-        public @Nullable Bundle getExtras() {
-            return mExtras;
-        }
-
-        /**
-         * Sets optional extras supplied by the application as part of the call to
-         * connect, or null if none.  The media route service may use this
-         * information to configure the route during connection.
-         */
-        public void setExtras(@Nullable Bundle extras) {
-            mExtras = extras;
-        }
-
-        @Override
-        public @NonNull String toString() {
-            return "ConnectionRequest{ route=" + mRoute
-                    + ", flags=0x" + Integer.toHexString(mFlags)
-                    + ", extras=" + mExtras + " }";
-        }
-    }
-
-    /**
-     * Callback interface to specify policy for route discovery, filtering,
-     * and connection establishment as well as observe media router state changes.
-     */
-    public static abstract class RoutingCallback extends StateCallback {
-        /**
-         * Called to prepare a discovery request object to specify the desired
-         * media route selectors when the media router has been asked to start discovery.
-         * <p>
-         * By default, the discovery request contains all of the selectors which
-         * have been added to the media router.  Subclasses may override the list of
-         * selectors by modifying the discovery request object before returning.
-         * </p>
-         *
-         * @param request The discovery request object which may be modified by
-         * this method to alter how discovery will be performed.
-         * @param selectors The immutable list of media route selectors which were
-         * added to the media router.
-         * @return True to allow discovery to proceed or false to abort it.
-         * By default, this methods returns true.
-         */
-        public boolean onPrepareDiscoveryRequest(@NonNull DiscoveryRequest request,
-                @NonNull List<MediaRouteSelector> selectors) {
-            return true;
-        }
-
-        /**
-         * Called to prepare a connection request object to specify the desired
-         * route and connection parameters when the media router has been asked to
-         * connect to a particular destination.
-         * <p>
-         * By default, the connection request specifies the first available route
-         * to the destination.  Subclasses may override the route and destination
-         * or set additional connection parameters by modifying the connection request
-         * object before returning.
-         * </p>
-         *
-         * @param request The connection request object which may be modified by
-         * this method to alter how the connection will be established.
-         * @param destination The destination to which the media router was asked
-         * to connect.
-         * @param routes The list of routes that belong to that destination sorted
-         * in the same order as their matching media route selectors which were
-         * used during discovery.
-         * @return True to allow the connection to proceed or false to abort it.
-         * By default, this methods returns true.
-         */
-        public boolean onPrepareConnectionRequest(
-                @NonNull ConnectionRequest request,
-                @NonNull DestinationInfo destination, @NonNull List<RouteInfo> routes) {
-            return true;
-        }
-    }
-
-    /**
-     * Callback class to receive events from a {@link MediaRouter.Delegate}.
-     */
-    public static abstract class StateCallback {
-        /**
-         * Called when the media router has been released.
-         */
-        public void onReleased() { }
-
-        /**
-         * Called when the discovery state has changed.
-         *
-         * @param state The new discovery state: one of
-         * {@link #DISCOVERY_STATE_STOPPED} or {@link #DISCOVERY_STATE_STARTED}.
-         */
-        public void onDiscoveryStateChanged(@DiscoveryState int state) { }
-
-        /**
-         * Called when the connection state has changed.
-         *
-         * @param state The new connection state: one of
-         * {@link #CONNECTION_STATE_DISCONNECTED}, {@link #CONNECTION_STATE_CONNECTING}
-         * or {@link #CONNECTION_STATE_CONNECTED}.
-         */
-        public void onConnectionStateChanged(@ConnectionState int state) { }
-
-        /**
-         * Called when the selected destination has changed.
-         *
-         * @param destination The new selected destination, or null if none.
-         */
-        public void onSelectedDestinationChanged(@Nullable DestinationInfo destination) { }
-
-        /**
-         * Called when route discovery has started.
-         */
-        public void onDiscoveryStarted() { }
-
-        /**
-         * Called when route discovery has stopped normally.
-         * <p>
-         * Abnormal termination is reported via {@link #onDiscoveryFailed}.
-         * </p>
-         */
-        public void onDiscoveryStopped() { }
-
-        /**
-         * Called when discovery has failed in a non-recoverable manner.
-         *
-         * @param error The error code: one of
-         * {@link MediaRouter#DISCOVERY_ERROR_UNKNOWN},
-         * {@link MediaRouter#DISCOVERY_ERROR_ABORTED},
-         * or {@link MediaRouter#DISCOVERY_ERROR_NO_CONNECTIVITY}.
-         * @param message The localized error message, or null if none.  This message
-         * may be shown to the user.
-         * @param extras Additional information about the error which a client
-         * may use, or null if none.
-         */
-        public void onDiscoveryFailed(@DiscoveryError int error, @Nullable CharSequence message,
-                @Nullable Bundle extras) { }
-
-        /**
-         * Called when a new destination is found or has changed during discovery.
-         * <p>
-         * Certain destinations may be omitted because they have been filtered
-         * out by the media router's routing callback.
-         * </p>
-         *
-         * @param destination The destination that was found.
-         */
-        public void onDestinationFound(@NonNull DestinationInfo destination) { }
-
-        /**
-         * Called when a destination is no longer reachable or is no longer
-         * offering any routes that satisfy the discovery request.
-         *
-         * @param destination The destination that went away.
-         */
-        public void onDestinationLost(@NonNull DestinationInfo destination) { }
-
-        /**
-         * Called when a connection attempt begins.
-         */
-        public void onConnecting() { }
-
-        /**
-         * Called when the connection succeeds.
-         */
-        public void onConnected() { }
-
-        /**
-         * Called when the connection is terminated normally.
-         * <p>
-         * Abnormal termination is reported via {@link #onConnectionFailed}.
-         * </p>
-         */
-        public void onDisconnected() { }
-
-        /**
-         * Called when a connection attempt or connection in
-         * progress has failed in a non-recoverable manner.
-         *
-         * @param error The error code: one of
-         * {@link MediaRouter#CONNECTION_ERROR_ABORTED},
-         * {@link MediaRouter#CONNECTION_ERROR_UNAUTHORIZED},
-         * {@link MediaRouter#CONNECTION_ERROR_UNREACHABLE},
-         * {@link MediaRouter#CONNECTION_ERROR_BUSY},
-         * {@link MediaRouter#CONNECTION_ERROR_TIMEOUT},
-         * {@link MediaRouter#CONNECTION_ERROR_BROKEN},
-         * or {@link MediaRouter#CONNECTION_ERROR_BARGED}.
-         * @param message The localized error message, or null if none.  This message
-         * may be shown to the user.
-         * @param extras Additional information about the error which a client
-         * may use, or null if none.
-         */
-        public void onConnectionFailed(@ConnectionError int error,
-                @Nullable CharSequence message, @Nullable Bundle extras) { }
-    }
-}
diff --git a/media/java/android/media/routing/ParcelableConnectionInfo.aidl b/media/java/android/media/routing/ParcelableConnectionInfo.aidl
deleted file mode 100644
index 4a9ec94..0000000
--- a/media/java/android/media/routing/ParcelableConnectionInfo.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 2014, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.media.routing;
-
-parcelable ParcelableConnectionInfo;
diff --git a/media/java/android/media/routing/ParcelableConnectionInfo.java b/media/java/android/media/routing/ParcelableConnectionInfo.java
deleted file mode 100644
index 45cfe9f..0000000
--- a/media/java/android/media/routing/ParcelableConnectionInfo.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.media.routing;
-
-import android.media.AudioAttributes;
-import android.os.Bundle;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Internal parcelable representation of a media route connection.
- */
-class ParcelableConnectionInfo implements Parcelable {
-    public AudioAttributes audioAttributes;
-    public int presentationDisplayId = -1;
-    // todo: volume
-    public IBinder[] protocolBinders;
-    public Bundle extras;
-
-    public static final Parcelable.Creator<ParcelableConnectionInfo> CREATOR =
-            new Parcelable.Creator<ParcelableConnectionInfo>() {
-        @Override
-        public ParcelableConnectionInfo createFromParcel(Parcel source) {
-            ParcelableConnectionInfo info = new ParcelableConnectionInfo();
-            if (source.readInt() != 0) {
-                info.audioAttributes = AudioAttributes.CREATOR.createFromParcel(source);
-            }
-            info.presentationDisplayId = source.readInt();
-            info.protocolBinders = source.createBinderArray();
-            info.extras = source.readBundle();
-            return info;
-        }
-
-        @Override
-        public ParcelableConnectionInfo[] newArray(int size) {
-            return new ParcelableConnectionInfo[size];
-        }
-    };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        if (audioAttributes != null) {
-            dest.writeInt(1);
-            audioAttributes.writeToParcel(dest, flags);
-        } else {
-            dest.writeInt(0);
-        }
-        dest.writeInt(presentationDisplayId);
-        dest.writeBinderArray(protocolBinders);
-        dest.writeBundle(extras);
-    }
-}
diff --git a/media/java/android/media/routing/ParcelableDestinationInfo.aidl b/media/java/android/media/routing/ParcelableDestinationInfo.aidl
deleted file mode 100644
index bf1c198..0000000
--- a/media/java/android/media/routing/ParcelableDestinationInfo.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 2014, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.media.routing;
-
-parcelable ParcelableDestinationInfo;
diff --git a/media/java/android/media/routing/ParcelableDestinationInfo.java b/media/java/android/media/routing/ParcelableDestinationInfo.java
deleted file mode 100644
index eca5eec..0000000
--- a/media/java/android/media/routing/ParcelableDestinationInfo.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.media.routing;
-
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-/**
- * Internal parcelable representation of a media destination.
- */
-class ParcelableDestinationInfo implements Parcelable {
-    public String id;
-    public CharSequence name;
-    public CharSequence description;
-    public int iconResourceId;
-    public Bundle extras;
-
-    public static final Parcelable.Creator<ParcelableDestinationInfo> CREATOR =
-            new Parcelable.Creator<ParcelableDestinationInfo>() {
-        @Override
-        public ParcelableDestinationInfo createFromParcel(Parcel source) {
-            ParcelableDestinationInfo info = new ParcelableDestinationInfo();
-            info.id = source.readString();
-            info.name = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
-            info.description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(source);
-            info.iconResourceId = source.readInt();
-            info.extras = source.readBundle();
-            return info;
-        }
-
-        @Override
-        public ParcelableDestinationInfo[] newArray(int size) {
-            return new ParcelableDestinationInfo[size];
-        }
-    };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(id);
-        TextUtils.writeToParcel(name, dest, flags);
-        TextUtils.writeToParcel(description, dest, flags);
-        dest.writeInt(iconResourceId);
-        dest.writeBundle(extras);
-    }
-}
diff --git a/media/java/android/media/routing/ParcelableRouteInfo.aidl b/media/java/android/media/routing/ParcelableRouteInfo.aidl
deleted file mode 100644
index 126afaa..0000000
--- a/media/java/android/media/routing/ParcelableRouteInfo.aidl
+++ /dev/null
@@ -1,18 +0,0 @@
-/* Copyright 2014, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-package android.media.routing;
-
-parcelable ParcelableRouteInfo;
diff --git a/media/java/android/media/routing/ParcelableRouteInfo.java b/media/java/android/media/routing/ParcelableRouteInfo.java
deleted file mode 100644
index fb1a547..0000000
--- a/media/java/android/media/routing/ParcelableRouteInfo.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package android.media.routing;
-
-import android.os.Bundle;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * Internal parcelable representation of a media route.
- */
-class ParcelableRouteInfo implements Parcelable {
-    public String id;
-    public int selectorIndex; // index of selector within list used for discovery
-    public int features;
-    public String[] protocols;
-    public Bundle extras;
-
-    public static final Parcelable.Creator<ParcelableRouteInfo> CREATOR =
-            new Parcelable.Creator<ParcelableRouteInfo>() {
-        @Override
-        public ParcelableRouteInfo createFromParcel(Parcel source) {
-            ParcelableRouteInfo info = new ParcelableRouteInfo();
-            info.id = source.readString();
-            info.selectorIndex = source.readInt();
-            info.features = source.readInt();
-            info.protocols = source.createStringArray();
-            info.extras = source.readBundle();
-            return info;
-        }
-
-        @Override
-        public ParcelableRouteInfo[] newArray(int size) {
-            return new ParcelableRouteInfo[size];
-        }
-    };
-
-    @Override
-    public int describeContents() {
-        return 0;
-    }
-
-    @Override
-    public void writeToParcel(Parcel dest, int flags) {
-        dest.writeString(id);
-        dest.writeInt(selectorIndex);
-        dest.writeInt(features);
-        dest.writeStringArray(protocols);
-        dest.writeBundle(extras);
-    }
-}
diff --git a/media/java/android/media/session/ISession.aidl b/media/java/android/media/session/ISession.aidl
index af3b72e..bd0019f 100644
--- a/media/java/android/media/session/ISession.aidl
+++ b/media/java/android/media/session/ISession.aidl
@@ -19,7 +19,6 @@
 import android.content.pm.ParceledListSlice;
 import android.media.AudioAttributes;
 import android.media.MediaMetadata;
-import android.media.routing.IMediaRouter;
 import android.media.session.ISessionController;
 import android.media.session.PlaybackState;
 import android.media.session.MediaSession;
@@ -35,7 +34,6 @@
     ISessionController getController();
     void setFlags(int flags);
     void setActive(boolean active);
-    void setMediaRouter(in IMediaRouter router);
     void setMediaButtonReceiver(in PendingIntent mbr);
     void setLaunchPendingIntent(in PendingIntent pi);
     void destroy();
diff --git a/media/java/android/media/session/ISessionController.aidl b/media/java/android/media/session/ISessionController.aidl
index 5764bd1..6b80477 100644
--- a/media/java/android/media/session/ISessionController.aidl
+++ b/media/java/android/media/session/ISessionController.aidl
@@ -20,8 +20,6 @@
 import android.content.pm.ParceledListSlice;
 import android.media.MediaMetadata;
 import android.media.Rating;
-import android.media.routing.IMediaRouterDelegate;
-import android.media.routing.IMediaRouterStateCallback;
 import android.media.session.ISessionControllerCallback;
 import android.media.session.ParcelableVolumeInfo;
 import android.media.session.PlaybackState;
@@ -51,8 +49,6 @@
     void adjustVolume(int direction, int flags, String packageName);
     void setVolumeTo(int value, int flags, String packageName);
 
-    IMediaRouterDelegate createMediaRouterDelegate(IMediaRouterStateCallback callback);
-
     // These commands are for the TransportControls
     void play();
     void playUri(in Uri uri, in Bundle extras);
diff --git a/media/java/android/media/session/MediaController.java b/media/java/android/media/session/MediaController.java
index 074e5ad..2ec0293 100644
--- a/media/java/android/media/session/MediaController.java
+++ b/media/java/android/media/session/MediaController.java
@@ -26,7 +26,6 @@
 import android.media.MediaMetadata;
 import android.media.Rating;
 import android.media.VolumeProvider;
-import android.media.routing.MediaRouter;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -119,17 +118,6 @@
     }
 
     /**
-     * Creates a media router delegate through which the destination of the media
-     * router may be observed and controlled.
-     *
-     * @return The media router delegate, or null if the media session does
-     * not support media routing.
-     */
-    public @Nullable MediaRouter.Delegate createMediaRouterDelegate() {
-        return new MediaRouter.Delegate();
-    }
-
-    /**
      * Send the specified media button event to the session. Only media keys can
      * be sent by this method, other keys will be ignored.
      *
diff --git a/media/java/android/media/session/MediaSession.java b/media/java/android/media/session/MediaSession.java
index 2cd161c..de725fc 100644
--- a/media/java/android/media/session/MediaSession.java
+++ b/media/java/android/media/session/MediaSession.java
@@ -28,7 +28,6 @@
 import android.media.MediaMetadata;
 import android.media.Rating;
 import android.media.VolumeProvider;
-import android.media.routing.MediaRouter;
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.Handler;
@@ -225,23 +224,6 @@
     }
 
     /**
-     * Associates a {@link MediaRouter} with this session to control the destination
-     * of media content.
-     * <p>
-     * A media router may only be associated with at most one session at a time.
-     * </p>
-     *
-     * @param router The media router, or null to remove the current association.
-     */
-    public void setMediaRouter(@Nullable MediaRouter router) {
-        try {
-            mBinder.setMediaRouter(router != null ? router.getBinder() : null);
-        } catch (RemoteException e) {
-            Log.wtf(TAG, "Failure in setMediaButtonReceiver.", 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
diff --git a/services/core/java/com/android/server/media/MediaSessionRecord.java b/services/core/java/com/android/server/media/MediaSessionRecord.java
index f820a3c..84027e2 100644
--- a/services/core/java/com/android/server/media/MediaSessionRecord.java
+++ b/services/core/java/com/android/server/media/MediaSessionRecord.java
@@ -26,9 +26,6 @@
 import android.media.MediaMetadata;
 import android.media.Rating;
 import android.media.VolumeProvider;
-import android.media.routing.IMediaRouter;
-import android.media.routing.IMediaRouterDelegate;
-import android.media.routing.IMediaRouterStateCallback;
 import android.media.session.ISession;
 import android.media.session.ISessionCallback;
 import android.media.session.ISessionController;
@@ -96,7 +93,6 @@
             new ArrayList<ISessionControllerCallback>();
 
     private long mFlags;
-    private IMediaRouter mMediaRouter;
     private PendingIntent mMediaButtonReceiver;
     private PendingIntent mLaunchIntent;
 
@@ -692,12 +688,6 @@
         }
 
         @Override
-        public void setMediaRouter(IMediaRouter router) {
-            mMediaRouter = router;
-            mHandler.post(MessageHandler.MSG_UPDATE_SESSION_STATE);
-        }
-
-        @Override
         public void setMediaButtonReceiver(PendingIntent pi) {
             mMediaButtonReceiver = pi;
         }
@@ -1147,13 +1137,6 @@
         public boolean isTransportControlEnabled() {
             return MediaSessionRecord.this.isTransportControlEnabled();
         }
-
-        @Override
-        public IMediaRouterDelegate createMediaRouterDelegate(
-                IMediaRouterStateCallback callback) {
-            // todo
-            return null;
-        }
     }
 
     private class MessageHandler extends Handler {
diff --git a/tests/OneMedia/Android.mk b/tests/OneMedia/Android.mk
index 4feac68..4d39728 100644
--- a/tests/OneMedia/Android.mk
+++ b/tests/OneMedia/Android.mk
@@ -9,9 +9,6 @@
 LOCAL_PACKAGE_NAME := OneMedia
 LOCAL_CERTIFICATE := platform
 
-LOCAL_STATIC_JAVA_LIBRARIES := \
-    android-support-media-protocols
-
 LOCAL_PROGUARD_ENABLED := disabled
 
 include $(BUILD_PACKAGE)
diff --git a/tests/OneMedia/AndroidManifest.xml b/tests/OneMedia/AndroidManifest.xml
index 95072a4..beafeb4 100644
--- a/tests/OneMedia/AndroidManifest.xml
+++ b/tests/OneMedia/AndroidManifest.xml
@@ -25,15 +25,6 @@
             android:name="com.android.onemedia.OnePlayerService"
             android:exported="true"
             android:process="com.android.onemedia.service" />
-        <service
-            android:name=".provider.OneMediaRouteProvider"
-            android:permission="android.permission.BIND_MEDIA_ROUTE_SERVICE"
-            android:exported="true"
-            android:process="com.android.onemedia.provider">
-            <intent-filter>
-                <action android:name="android.media.routing.MediaRouteService" />
-            </intent-filter>
-          </service>
     </application>
 
 </manifest>
diff --git a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
index 9afcf24..8b7c883 100644
--- a/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
+++ b/tests/OneMedia/src/com/android/onemedia/PlayerSession.java
@@ -19,24 +19,16 @@
 import android.content.Intent;
 import android.graphics.Bitmap;
 import android.media.MediaMetadata;
-import android.media.routing.MediaRouteSelector;
-import android.media.routing.MediaRouter;
-import android.media.routing.MediaRouter.ConnectionRequest;
-import android.media.routing.MediaRouter.DestinationInfo;
-import android.media.routing.MediaRouter.RouteInfo;
 import android.media.session.MediaSession;
 import android.media.session.MediaSessionManager;
 import android.media.session.PlaybackState;
 import android.os.Bundle;
-import android.support.media.protocols.MediaPlayerProtocol;
-import android.support.media.protocols.MediaPlayerProtocol.MediaStatus;
 import android.os.RemoteException;
 import android.os.SystemClock;
 import android.util.Log;
 import android.view.KeyEvent;
 
 import com.android.onemedia.playback.LocalRenderer;
-import com.android.onemedia.playback.OneMRPRenderer;
 import com.android.onemedia.playback.Renderer;
 import com.android.onemedia.playback.RequestUtils;
 
@@ -47,7 +39,6 @@
     private static final String TAG = "PlayerSession";
 
     protected MediaSession mSession;
-    protected MediaRouter mRouter;
     protected Context mContext;
     protected Renderer mRenderer;
     protected MediaSession.Callback mCallback;
@@ -80,22 +71,11 @@
                 .getSystemService(Context.MEDIA_SESSION_SERVICE);
         Log.d(TAG, "Creating session for package " + mContext.getBasePackageName());
 
-        mRouter = new MediaRouter(mContext);
-        mRouter.addSelector(new MediaRouteSelector.Builder()
-                .addRequiredProtocol(MediaPlayerProtocol.class)
-                .build());
-        mRouter.addSelector(new MediaRouteSelector.Builder()
-                .setRequiredFeatures(MediaRouter.ROUTE_FEATURE_LIVE_AUDIO)
-                .setOptionalFeatures(MediaRouter.ROUTE_FEATURE_LIVE_VIDEO)
-                .build());
-        mRouter.setRoutingCallback(new RoutingCallback(), null);
-
         mSession = new MediaSession(mContext, "OneMedia");
         mSession.setCallback(mCallback);
         mSession.setPlaybackState(mPlaybackState);
         mSession.setFlags(MediaSession.FLAG_HANDLES_TRANSPORT_CONTROLS
                 | MediaSession.FLAG_HANDLES_MEDIA_BUTTONS);
-        mSession.setMediaRouter(mRouter);
         mSession.setActive(true);
         updateMetadata();
     }
@@ -113,10 +93,6 @@
             mSession.release();
             mSession = null;
         }
-        if (mRouter != null) {
-            mRouter.release();
-            mRouter = null;
-        }
     }
 
     public void setListener(Listener listener) {
@@ -266,63 +242,4 @@
             mRenderer.onPause();
         }
     }
-
-    private class RoutingCallback extends MediaRouter.RoutingCallback {
-        @Override
-        public void onConnectionStateChanged(int state) {
-            if (state == MediaRouter.CONNECTION_STATE_CONNECTING) {
-                if (mRenderer != null) {
-                    mRenderer.onStop();
-                }
-                mRenderer = null;
-                updateState(PlaybackState.STATE_CONNECTING);
-                return;
-            }
-
-            MediaRouter.ConnectionInfo connection = mRouter.getConnection();
-            if (connection != null) {
-                MediaPlayerProtocol protocol =
-                        connection.getProtocolObject(MediaPlayerProtocol.class);
-                if (protocol != null) {
-                    Log.d(TAG, "Connected to route using media player protocol");
-
-                    protocol.setCallback(new PlayerCallback(), null);
-                    mRenderer = new OneMRPRenderer(protocol);
-                    updateState(PlaybackState.STATE_NONE);
-                    return;
-                }
-            }
-
-            // Use local route
-            mRenderer = new LocalRenderer(mContext, null);
-            mRenderer.registerListener(mRenderListener);
-            updateState(PlaybackState.STATE_NONE);
-        }
-    }
-
-    private class PlayerCallback extends MediaPlayerProtocol.Callback {
-        @Override
-        public void onStatusUpdated(MediaStatus status, Bundle extras) {
-            if (status != null) {
-                Log.d(TAG, "Received status update: " + status.toBundle());
-                switch (status.getPlayerState()) {
-                    case MediaStatus.PLAYER_STATE_BUFFERING:
-                        updateState(PlaybackState.STATE_BUFFERING);
-                        break;
-                    case MediaStatus.PLAYER_STATE_IDLE:
-                        updateState(PlaybackState.STATE_STOPPED);
-                        break;
-                    case MediaStatus.PLAYER_STATE_PAUSED:
-                        updateState(PlaybackState.STATE_PAUSED);
-                        break;
-                    case MediaStatus.PLAYER_STATE_PLAYING:
-                        updateState(PlaybackState.STATE_PLAYING);
-                        break;
-                    case MediaStatus.PLAYER_STATE_UNKNOWN:
-                        updateState(PlaybackState.STATE_NONE);
-                        break;
-                }
-            }
-        }
-    }
 }
diff --git a/tests/OneMedia/src/com/android/onemedia/playback/OneMRPRenderer.java b/tests/OneMedia/src/com/android/onemedia/playback/OneMRPRenderer.java
deleted file mode 100644
index 55eb92c..0000000
--- a/tests/OneMedia/src/com/android/onemedia/playback/OneMRPRenderer.java
+++ /dev/null
@@ -1,47 +0,0 @@
-package com.android.onemedia.playback;
-
-import android.os.Bundle;
-import android.support.media.protocols.MediaPlayerProtocol;
-import android.support.media.protocols.MediaPlayerProtocol.MediaInfo;
-
-/**
- * Renderer for communicating with the OneMRP route
- */
-public class OneMRPRenderer extends Renderer {
-    private final MediaPlayerProtocol mProtocol;
-
-    public OneMRPRenderer(MediaPlayerProtocol protocol) {
-        super(null, null);
-        mProtocol = protocol;
-    }
-
-    @Override
-    public void setContent(Bundle request) {
-        MediaInfo mediaInfo = new MediaInfo(request.getString(RequestUtils.EXTRA_KEY_SOURCE),
-                MediaInfo.STREAM_TYPE_BUFFERED, "audio/mp3");
-        mProtocol.load(mediaInfo, true, 0, null);
-    }
-
-    @Override
-    public boolean onStop() {
-        mProtocol.stop(null);
-        return true;
-    }
-
-    @Override
-    public boolean onPlay() {
-        mProtocol.play(null);
-        return true;
-    }
-
-    @Override
-    public boolean onPause() {
-        mProtocol.pause(null);
-        return true;
-    }
-
-    @Override
-    public long getSeekPosition() {
-        return -1;
-    }
-}
diff --git a/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java b/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java
deleted file mode 100644
index 5845e48..0000000
--- a/tests/OneMedia/src/com/android/onemedia/provider/OneMediaRouteProvider.java
+++ /dev/null
@@ -1,270 +0,0 @@
-/*
- * Copyright (C) 2014 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.android.onemedia.provider;
-
-import android.media.routing.MediaRouteSelector;
-import android.media.routing.MediaRouteService;
-import android.media.routing.MediaRouter.ConnectionInfo;
-import android.media.routing.MediaRouter.ConnectionRequest;
-import android.media.routing.MediaRouter.DestinationInfo;
-import android.media.routing.MediaRouter.DiscoveryRequest;
-import android.media.routing.MediaRouter.RouteInfo;
-import android.media.session.PlaybackState;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Process;
-import android.support.media.protocols.MediaPlayerProtocol;
-import android.support.media.protocols.MediaPlayerProtocol.MediaInfo;
-import android.support.media.protocols.MediaPlayerProtocol.MediaStatus;
-import android.os.Looper;
-import android.os.ResultReceiver;
-import android.os.SystemClock;
-import android.util.Log;
-
-import com.android.onemedia.playback.LocalRenderer;
-import com.android.onemedia.playback.Renderer;
-import com.android.onemedia.playback.RequestUtils;
-
-import java.util.ArrayList;
-
-/**
- * Test of MediaRouteProvider. Show a dummy provider with a simple interface for
- * playing music.
- */
-public class OneMediaRouteProvider extends MediaRouteService {
-    private static final String TAG = "OneMRP";
-    private static final boolean DEBUG = true;
-
-    private static final String TEST_DESTINATION_ID = "testDestination";
-    private static final String TEST_ROUTE_ID = "testRoute";
-
-    private Renderer mRenderer;
-    private RenderListener mRenderListener;
-    private PlaybackState mPlaybackState;
-    private Handler mHandler;
-
-    private OneStub mStub;
-
-    @Override
-    public void onCreate() {
-        mHandler = new Handler();
-        mRenderer = new LocalRenderer(this, null);
-        mRenderListener = new RenderListener();
-        PlaybackState.Builder bob = new PlaybackState.Builder();
-        bob.setActions(PlaybackState.ACTION_PAUSE | PlaybackState.ACTION_PLAY);
-        mPlaybackState = bob.build();
-
-        mRenderer.registerListener(mRenderListener);
-    }
-
-    @Override
-    public ClientSession onCreateClientSession(ClientInfo client) {
-        if (client.getUid() != Process.myUid()) {
-            // for testing purposes, only allow connections from this application
-            // since this provider is not fully featured
-            return null;
-        }
-        return new OneSession(client);
-    }
-
-    private final class OneSession extends ClientSession {
-        private final ClientInfo mClient;
-
-        public OneSession(ClientInfo client) {
-            mClient = client;
-        }
-
-        @Override
-        public boolean onStartDiscovery(DiscoveryRequest req, DiscoveryCallback callback) {
-            for (MediaRouteSelector selector : req.getSelectors()) {
-                if (isMatch(selector)) {
-                    DestinationInfo destination = new DestinationInfo.Builder(
-                            TEST_DESTINATION_ID, getServiceMetadata(), "OneMedia")
-                            .setDescription("Test route from OneMedia app.")
-                            .build();
-                    ArrayList<RouteInfo> routes = new ArrayList<RouteInfo>();
-                    routes.add(new RouteInfo.Builder(
-                            TEST_ROUTE_ID, destination, selector).build());
-                    callback.onDestinationFound(destination, routes);
-                    return true;
-                }
-            }
-            return false;
-        }
-
-        @Override
-        public void onStopDiscovery() {
-        }
-
-        @Override
-        public boolean onConnect(ConnectionRequest req, ConnectionCallback callback) {
-            if (req.getRoute().getId().equals(TEST_ROUTE_ID)) {
-                mStub = new OneStub();
-                ConnectionInfo connection = new ConnectionInfo.Builder(req.getRoute())
-                        .setProtocolStub(MediaPlayerProtocol.class, mStub)
-                        .build();
-                callback.onConnected(connection);
-                return true;
-            }
-            return false;
-        }
-
-        @Override
-        public void onDisconnect() {
-            mStub = null;
-        }
-
-        private boolean isMatch(MediaRouteSelector selector) {
-            if (!selector.containsProtocol(MediaPlayerProtocol.class)) {
-                return false;
-            }
-            for (String protocol : selector.getRequiredProtocols()) {
-                if (!protocol.equals(MediaPlayerProtocol.class.getName())) {
-                    return false;
-                }
-            }
-            return true;
-        }
-    }
-
-    private final class OneStub extends MediaPlayerProtocol.Stub {
-        MediaInfo mMediaInfo;
-
-        public OneStub() {
-            super(mHandler);
-        }
-
-        @Override
-        public void onLoad(MediaInfo mediaInfo, boolean autoplay, long playPosition,
-                Bundle extras) {
-            if (DEBUG) {
-                Log.d(TAG, "Attempting to play " + mediaInfo.getContentId());
-            }
-            // look up the route and send a play command to it
-            mMediaInfo = mediaInfo;
-            Bundle bundle = new Bundle();
-            bundle.putString(RequestUtils.EXTRA_KEY_SOURCE, mediaInfo.getContentId());
-            mRenderer.setContent(bundle);
-        }
-
-        @Override
-        public void onPlay(Bundle extras) {
-            mRenderer.onPlay();
-        }
-
-        @Override
-        public void onPause(Bundle extras) {
-            mRenderer.onPause();
-        }
-    }
-
-    private class RenderListener implements Renderer.Listener {
-
-        @Override
-        public void onError(int type, int extra, Bundle extras, Throwable error) {
-            Log.d(TAG, "Sending onError with type " + type + " and extra " + extra);
-            sendStatusUpdate(PlaybackState.STATE_ERROR);
-        }
-
-        @Override
-        public void onStateChanged(int newState) {
-            long position = -1;
-            if (mRenderer != null) {
-                position = mRenderer.getSeekPosition();
-            }
-            int pbState;
-            float rate = 0;
-            String errorMsg = null;
-            switch (newState) {
-                case Renderer.STATE_ENDED:
-                case Renderer.STATE_STOPPED:
-                    pbState = PlaybackState.STATE_STOPPED;
-                    break;
-                case Renderer.STATE_INIT:
-                case Renderer.STATE_PREPARING:
-                    pbState = PlaybackState.STATE_BUFFERING;
-                    break;
-                case Renderer.STATE_ERROR:
-                    pbState = PlaybackState.STATE_ERROR;
-                    break;
-                case Renderer.STATE_PAUSED:
-                    pbState = PlaybackState.STATE_PAUSED;
-                    break;
-                case Renderer.STATE_PLAYING:
-                    pbState = PlaybackState.STATE_PLAYING;
-                    rate = 1;
-                    break;
-                default:
-                    pbState = PlaybackState.STATE_ERROR;
-                    errorMsg = "unknown state";
-                    break;
-            }
-            PlaybackState.Builder bob = new PlaybackState.Builder(mPlaybackState);
-            bob.setState(pbState, position, rate, SystemClock.elapsedRealtime());
-            bob.setErrorMessage(errorMsg);
-            mPlaybackState = bob.build();
-
-            sendStatusUpdate(mPlaybackState.getState());
-        }
-
-        @Override
-        public void onBufferingUpdate(int percent) {
-        }
-
-        @Override
-        public void onFocusLost() {
-            Log.d(TAG, "Focus lost, pausing");
-            // Don't update state here, we'll get a separate call to
-            // onStateChanged when it pauses
-            mRenderer.onPause();
-        }
-
-        @Override
-        public void onNextStarted() {
-        }
-
-        private void sendStatusUpdate(int state) {
-            if (mStub != null) {
-                MediaStatus status = new MediaStatus(1, mStub.mMediaInfo);
-                switch (state) {
-                    case PlaybackState.STATE_BUFFERING:
-                    case PlaybackState.STATE_FAST_FORWARDING:
-                    case PlaybackState.STATE_REWINDING:
-                    case PlaybackState.STATE_SKIPPING_TO_NEXT:
-                    case PlaybackState.STATE_SKIPPING_TO_PREVIOUS:
-                        status.setPlayerState(MediaStatus.PLAYER_STATE_BUFFERING);
-                        break;
-                    case PlaybackState.STATE_CONNECTING:
-                    case PlaybackState.STATE_STOPPED:
-                        status.setPlayerState(MediaStatus.PLAYER_STATE_IDLE);
-                        break;
-                    case PlaybackState.STATE_PAUSED:
-                        status.setPlayerState(MediaStatus.PLAYER_STATE_PAUSED);
-                        break;
-                    case PlaybackState.STATE_PLAYING:
-                        status.setPlayerState(MediaStatus.PLAYER_STATE_PLAYING);
-                        break;
-                    case PlaybackState.STATE_NONE:
-                    case PlaybackState.STATE_ERROR:
-                    default:
-                        status.setPlayerState(MediaStatus.PLAYER_STATE_UNKNOWN);
-                        break;
-                }
-                mStub.sendStatusUpdatedEvent(status, null);
-            }
-        }
-    }
-}
