Remove incomplete media router API. (DO NOT MERGE)

Change-Id: I310fadafb5a6b8190a32e5d87f3e1823c87bcef7
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);
-            }
-        }
-    }
-}