MediaRouter: make route controllers return route info

Since RouteSessionInfo holds lists of route ids which are unique
only in a provider, ids returned by RouteSessionController can't be
used to identify routes from different providers.

Using provider id in the route session together, route controller
can return route infos that can be used directly by end users.

Test: atest mediaroutertest
Change-Id: I0dbbae2b66f5c1c77c9a9b624fcf924c9e1a280a
diff --git a/media/java/android/media/MediaRoute2Info.java b/media/java/android/media/MediaRoute2Info.java
index d919d78..506d616 100644
--- a/media/java/android/media/MediaRoute2Info.java
+++ b/media/java/android/media/MediaRoute2Info.java
@@ -195,11 +195,15 @@
     private String createUniqueId() {
         String uniqueId = null;
         if (mProviderId != null) {
-            uniqueId = mProviderId + ":" + mId;
+            uniqueId = toUniqueId(mProviderId, mId);
         }
         return uniqueId;
     }
 
+    static String toUniqueId(String providerId, String routeId) {
+        return providerId + ":" + routeId;
+    }
+
     /**
      * Returns true if the route info has all of the required field.
      * A route info only obtained from {@link com.android.server.media.MediaRouterService}
diff --git a/media/java/android/media/MediaRouter2.java b/media/java/android/media/MediaRouter2.java
index 046a8bb..600e630 100644
--- a/media/java/android/media/MediaRouter2.java
+++ b/media/java/android/media/MediaRouter2.java
@@ -110,7 +110,7 @@
 
     private final String mPackageName;
     @GuardedBy("sLock")
-    private final Map<String, MediaRoute2Info> mRoutes = new HashMap<>();
+    final Map<String, MediaRoute2Info> mRoutes = new HashMap<>();
 
     @GuardedBy("sLock")
     private List<String> mControlCategories = Collections.emptyList();
@@ -678,8 +678,6 @@
      * A class to control media route session in media route provider.
      * For example, selecting/deselcting/transferring routes to session can be done through this
      * class. Instances are created by {@link MediaRouter2}.
-     *
-     * @hide
      */
     public final class RouteSessionController {
         private final Object mLock = new Object();
@@ -724,42 +722,42 @@
         }
 
         /**
-         * @return the unmodifiable list of IDs of currently selected routes
+         * @return the unmodifiable list of currently selected routes
          */
         @NonNull
-        public List<String> getSelectedRoutes() {
+        public List<MediaRoute2Info> getSelectedRoutes() {
             synchronized (mLock) {
-                return Collections.unmodifiableList(mSessionInfo.getSelectedRoutes());
+                return getRoutesWithIdsLocked(mSessionInfo.getSelectedRoutes());
             }
         }
 
         /**
-         * @return the unmodifiable list of IDs of selectable routes for the session.
+         * @return the unmodifiable list of selectable routes for the session.
          */
         @NonNull
-        public List<String> getSelectableRoutes() {
+        public List<MediaRoute2Info> getSelectableRoutes() {
             synchronized (mLock) {
-                return Collections.unmodifiableList(mSessionInfo.getSelectableRoutes());
+                return getRoutesWithIdsLocked(mSessionInfo.getSelectableRoutes());
             }
         }
 
         /**
-         * @return the unmodifiable list of IDs of deselectable routes for the session.
+         * @return the unmodifiable list of deselectable routes for the session.
          */
         @NonNull
-        public List<String> getDeselectableRoutes() {
+        public List<MediaRoute2Info> getDeselectableRoutes() {
             synchronized (mLock) {
-                return Collections.unmodifiableList(mSessionInfo.getDeselectableRoutes());
+                return getRoutesWithIdsLocked(mSessionInfo.getDeselectableRoutes());
             }
         }
 
         /**
-         * @return the unmodifiable list of IDs of transferrable routes for the session.
+         * @return the unmodifiable list of transferrable routes for the session.
          */
         @NonNull
-        public List<String> getTransferrableRoutes() {
+        public List<MediaRoute2Info> getTransferrableRoutes() {
             synchronized (mLock) {
-                return Collections.unmodifiableList(mSessionInfo.getTransferrableRoutes());
+                return getRoutesWithIdsLocked(mSessionInfo.getTransferrableRoutes());
             }
         }
 
@@ -784,7 +782,7 @@
          * @see #getSelectedRoutes()
          * @see SessionCallback#onSessionInfoChanged
          */
-        public void selectRoute(MediaRoute2Info route) {
+        public void selectRoute(@NonNull MediaRoute2Info route) {
             // TODO: Implement this when the actual connection logic is implemented.
         }
 
@@ -796,7 +794,7 @@
          * @see #getSelectedRoutes()
          * @see SessionCallback#onSessionInfoChanged
          */
-        public void deselectRoute(MediaRoute2Info route) {
+        public void deselectRoute(@NonNull MediaRoute2Info route) {
             // TODO: Implement this when the actual connection logic is implemented.
         }
 
@@ -817,6 +815,20 @@
             }
             // TODO: Use stopMedia variable when the actual connection logic is implemented.
         }
+
+        private List<MediaRoute2Info> getRoutesWithIdsLocked(List<String> routeIds) {
+            List<MediaRoute2Info> routes = new ArrayList<>();
+            synchronized (mLock) {
+                for (String routeId : routeIds) {
+                    MediaRoute2Info route = mRoutes.get(
+                            MediaRoute2Info.toUniqueId(mSessionInfo.mProviderId, routeId));
+                    if (route != null) {
+                        routes.add(route);
+                    }
+                }
+            }
+            return Collections.unmodifiableList(routes);
+        }
     }
 
     final class RouteCallbackRecord {
diff --git a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java
index 6e79dd1..0c4c437 100644
--- a/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java
+++ b/media/tests/MediaRouter/src/com/android/mediaroutertest/MediaRouter2Test.java
@@ -260,7 +260,7 @@
             @Override
             public void onSessionCreated(RouteSessionController controller) {
                 assertNotNull(controller);
-                assertTrue(controller.getSelectedRoutes().contains(ROUTE_ID1));
+                assertTrue(createRouteMap(controller.getSelectedRoutes()).containsKey(ROUTE_ID1));
                 assertTrue(TextUtils.equals(CATEGORY_SAMPLE, controller.getControlCategory()));
                 successLatch.countDown();
             }
@@ -384,8 +384,8 @@
             RouteSessionController controller2 = createdControllers.get(1);
 
             assertNotEquals(controller1.getSessionId(), controller2.getSessionId());
-            assertTrue(controller1.getSelectedRoutes().contains(ROUTE_ID1));
-            assertTrue(controller2.getSelectedRoutes().contains(ROUTE_ID2));
+            assertTrue(createRouteMap(controller1.getSelectedRoutes()).containsKey(ROUTE_ID1));
+            assertTrue(createRouteMap(controller2.getSelectedRoutes()).containsKey(ROUTE_ID2));
             assertTrue(TextUtils.equals(CATEGORY_SAMPLE, controller1.getControlCategory()));
             assertTrue(TextUtils.equals(CATEGORY_SAMPLE, controller2.getControlCategory()));
         } finally {