MediaRouter: Overload onCreateRouteController for route groups

onCreateRouteController is called when a route is selected. This
CL overloads the method with an additional parameter, routeGroupId.
The overloaded method will be called when the route is selected by
selecting a route group where the route is a member of the route
group.

Bug: 29194434
Change-Id: I6582a7bc6f18119578a60ad67d4be865a965dace
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouteProvider.java b/v7/mediarouter/src/android/support/v7/media/MediaRouteProvider.java
index f370e95..a9c3ed2 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouteProvider.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouteProvider.java
@@ -250,11 +250,40 @@
      * cannot be controlled using the route controller interface.
      */
     @Nullable
-    public RouteController onCreateRouteController(String routeId) {
+    public RouteController onCreateRouteController(@NonNull String routeId) {
+        if (routeId == null) {
+            throw new IllegalArgumentException("routeId cannot be null");
+        }
         return null;
     }
 
     /**
+     * Called by the media router to obtain a route controller for a particular route which is a
+     * member of {@link MediaRouter.RouteGroup}.
+     * <p>
+     * The media router will invoke the {@link RouteController#onRelease} method of the route
+     * controller when it is no longer needed to allow it to free its resources.
+     * </p>
+     *
+     * @param routeId The unique id of the member route.
+     * @param routeGroupId The unique id of the route group.
+     * @return The route controller.  Returns null if there is no such route or if the route
+     * cannot be controlled using the route controller interface.
+     * @hide
+     */
+    @Nullable
+    public RouteController onCreateRouteController(@NonNull String routeId,
+            @NonNull String routeGroupId) {
+        if (routeId == null) {
+            throw new IllegalArgumentException("routeId cannot be null");
+        }
+        if (routeGroupId == null) {
+            throw new IllegalArgumentException("routeGroupId cannot be null");
+        }
+        return onCreateRouteController(routeId);
+    }
+
+    /**
      * Describes properties of the route provider's implementation.
      * <p>
      * This object is immutable once created.
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderProtocol.java b/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderProtocol.java
index 3f0976f..0339e89 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderProtocol.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderProtocol.java
@@ -120,6 +120,7 @@
     public static final int CLIENT_MSG_SET_DISCOVERY_REQUEST = 10;
 
     public static final String CLIENT_DATA_ROUTE_ID = "routeId";
+    public static final String CLIENT_DATA_ROUTE_GROUP_ID = "routeGroupId";
     public static final String CLIENT_DATA_VOLUME = "volume";
     public static final String CLIENT_DATA_UNSELECT_REASON = "unselectReason";
 
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderService.java b/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderService.java
index 343d21b..bd2e214 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderService.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouteProviderService.java
@@ -198,13 +198,13 @@
     }
 
     private boolean onCreateRouteController(Messenger messenger, int requestId,
-            int controllerId, String routeId) {
+            int controllerId, String routeId, String routeGroupId) {
         ClientRecord client = getClient(messenger);
         if (client != null) {
-            if (client.createRouteController(routeId, controllerId)) {
+            if (client.createRouteController(routeId, routeGroupId, controllerId)) {
                 if (DEBUG) {
-                    Log.d(TAG, client + ": Route controller created"
-                            + ", controllerId=" + controllerId + ", routeId=" + routeId);
+                    Log.d(TAG, client + ": Route controller created, controllerId=" + controllerId
+                            + ", routeId=" + routeId + ", routeGroupId=" + routeGroupId);
                 }
                 sendGenericSuccess(messenger, requestId);
                 return true;
@@ -532,10 +532,12 @@
             return mMessenger.getBinder() == other.getBinder();
         }
 
-        public boolean createRouteController(String routeId, int controllerId) {
+        public boolean createRouteController(String routeId, String routeGroupId,
+                int controllerId) {
             if (mControllers.indexOfKey(controllerId) < 0) {
-                MediaRouteProvider.RouteController controller =
-                        mProvider.onCreateRouteController(routeId);
+                MediaRouteProvider.RouteController controller = routeGroupId == null
+                        ? mProvider.onCreateRouteController(routeId)
+                        : mProvider.onCreateRouteController(routeId, routeGroupId);
                 if (controller != null) {
                     mControllers.put(controllerId, controller);
                     return true;
@@ -634,9 +636,10 @@
 
                     case CLIENT_MSG_CREATE_ROUTE_CONTROLLER: {
                         String routeId = data.getString(CLIENT_DATA_ROUTE_ID);
+                        String routeGroupId = data.getString(CLIENT_DATA_ROUTE_GROUP_ID);
                         if (routeId != null) {
                             return service.onCreateRouteController(
-                                    messenger, requestId, arg, routeId);
+                                    messenger, requestId, arg, routeId, routeGroupId);
                         }
                         break;
                     }
diff --git a/v7/mediarouter/src/android/support/v7/media/MediaRouter.java b/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
index f8c76dc..3a0a0eb 100644
--- a/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
+++ b/v7/mediarouter/src/android/support/v7/media/MediaRouter.java
@@ -2539,8 +2539,9 @@
                         List<RouteInfo> routes = ((RouteGroup) mSelectedRoute).getRoutes();
                         mRouteControllerMap.clear();
                         for (RouteInfo r : routes) {
-                            RouteController controller = r.getProviderInstance()
-                                    .onCreateRouteController(r.mDescriptorId);
+                            RouteController controller =
+                                    r.getProviderInstance().onCreateRouteController(
+                                            r.mDescriptorId, mSelectedRoute.mDescriptorId);
                             controller.onSelect();
                             mRouteControllerMap.put(r.mDescriptorId, controller);
                         }
diff --git a/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProvider.java b/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProvider.java
index e4360b3..df77c5d 100644
--- a/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProvider.java
+++ b/v7/mediarouter/src/android/support/v7/media/RegisteredMediaRouteProvider.java
@@ -28,6 +28,7 @@
 import android.os.IBinder.DeathRecipient;
 import android.os.Message;
 import android.os.Messenger;
+import android.support.annotation.NonNull;
 import android.support.v7.media.MediaRouter.ControlRequestCallback;
 import android.util.Log;
 import android.util.SparseArray;
@@ -63,25 +64,23 @@
     }
 
     @Override
-    public RouteController onCreateRouteController(String routeId) {
-        MediaRouteProviderDescriptor descriptor = getDescriptor();
-        if (descriptor != null) {
-            List<MediaRouteDescriptor> routes = descriptor.getRoutes();
-            final int count = routes.size();
-            for (int i = 0; i < count; i++) {
-                final MediaRouteDescriptor route = routes.get(i);
-                if (route.getId().equals(routeId)) {
-                    Controller controller = new Controller(routeId);
-                    mControllers.add(controller);
-                    if (mConnectionReady) {
-                        controller.attachConnection(mActiveConnection);
-                    }
-                    updateBinding();
-                    return controller;
-                }
-            }
+    public RouteController onCreateRouteController(@NonNull String routeId) {
+        if (routeId == null) {
+            throw new IllegalArgumentException("routeId cannot be null");
         }
-        return null;
+        return createRouteController(routeId, null);
+    }
+
+    @Override
+    public RouteController onCreateRouteController(
+            @NonNull String routeId, @NonNull String routeGroupId) {
+        if (routeId == null) {
+            throw new IllegalArgumentException("routeId cannot be null");
+        }
+        if (routeGroupId == null) {
+            throw new IllegalArgumentException("routeGroupId cannot be null");
+        }
+        return createRouteController(routeId, routeGroupId);
     }
 
     @Override
@@ -216,6 +215,27 @@
         disconnect();
     }
 
+    private RouteController createRouteController(String routeId, String routeGroupId) {
+        MediaRouteProviderDescriptor descriptor = getDescriptor();
+        if (descriptor != null) {
+            List<MediaRouteDescriptor> routes = descriptor.getRoutes();
+            final int count = routes.size();
+            for (int i = 0; i < count; i++) {
+                final MediaRouteDescriptor route = routes.get(i);
+                if (route.getId().equals(routeId)) {
+                    Controller controller = new Controller(routeId, routeGroupId);
+                    mControllers.add(controller);
+                    if (mConnectionReady) {
+                        controller.attachConnection(mActiveConnection);
+                    }
+                    updateBinding();
+                    return controller;
+                }
+            }
+        }
+        return null;
+    }
+
     private void onConnectionReady(Connection connection) {
         if (mActiveConnection == connection) {
             mConnectionReady = true;
@@ -293,6 +313,7 @@
 
     private final class Controller extends RouteController {
         private final String mRouteId;
+        private final String mRouteGroupId;
 
         private boolean mSelected;
         private int mPendingSetVolume = -1;
@@ -301,13 +322,14 @@
         private Connection mConnection;
         private int mControllerId;
 
-        public Controller(String routeId) {
+        public Controller(String routeId, String routeGroupId) {
             mRouteId = routeId;
+            mRouteGroupId = routeGroupId;
         }
 
         public void attachConnection(Connection connection) {
             mConnection = connection;
-            mControllerId = connection.createRouteController(mRouteId);
+            mControllerId = connection.createRouteController(mRouteId, mRouteGroupId);
             if (mSelected) {
                 connection.selectRoute(mControllerId);
                 if (mPendingSetVolume >= 0) {
@@ -511,10 +533,11 @@
             });
         }
 
-        public int createRouteController(String routeId) {
+        public int createRouteController(String routeId, String routeGroupId) {
             int controllerId = mNextControllerId++;
             Bundle data = new Bundle();
             data.putString(CLIENT_DATA_ROUTE_ID, routeId);
+            data.putString(CLIENT_DATA_ROUTE_GROUP_ID, routeGroupId);
             sendRequest(CLIENT_MSG_CREATE_ROUTE_CONTROLLER,
                     mNextRequestId++, controllerId, null, data);
             return controllerId;