124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown/* 224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Copyright (C) 2013 The Android Open Source Project 324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * you may not use this file except in compliance with the License. 624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * You may obtain a copy of the License at 724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * http://www.apache.org/licenses/LICENSE-2.0 924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * 1024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Unless required by applicable law or agreed to in writing, software 1124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 1224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * See the License for the specific language governing permissions and 1424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * limitations under the License. 1524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 1624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 1724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownpackage android.support.v4.media.routing; 1824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 1924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.content.Context; 2024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.graphics.drawable.Drawable; 2124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.os.Build; 2224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport android.util.Log; 2324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 2424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport java.lang.reflect.InvocationTargetException; 2524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport java.lang.reflect.Method; 2624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport java.util.ArrayList; 2724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownimport java.util.List; 2824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 2924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brownclass MediaRouterJellybean { 3024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private static final String TAG = "MediaRouterJellybean"; 3124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 3224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static final int ROUTE_TYPE_LIVE_AUDIO = 0x1; 3324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static final int ROUTE_TYPE_LIVE_VIDEO = 0x2; 3424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static final int ROUTE_TYPE_USER = 0x00800000; 3524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 3624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static final int ALL_ROUTE_TYPES = 3724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown MediaRouterJellybean.ROUTE_TYPE_LIVE_AUDIO 3824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown | MediaRouterJellybean.ROUTE_TYPE_LIVE_VIDEO 3924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown | MediaRouterJellybean.ROUTE_TYPE_USER; 4024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 4124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static Object getMediaRouter(Context context) { 4224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return context.getSystemService(Context.MEDIA_ROUTER_SERVICE); 4324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 4424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 4524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @SuppressWarnings({ "rawtypes", "unchecked" }) 4624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static List getRoutes(Object routerObj) { 4724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown final android.media.MediaRouter router = (android.media.MediaRouter)routerObj; 4824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown final int count = router.getRouteCount(); 4924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown List out = new ArrayList(count); 5024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown for (int i = 0; i < count; i++) { 5124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown out.add(router.getRouteAt(i)); 5224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 5324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return out; 5424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 5524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 5624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @SuppressWarnings({ "rawtypes", "unchecked" }) 5724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static List getCategories(Object routerObj) { 5824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown final android.media.MediaRouter router = (android.media.MediaRouter)routerObj; 5924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown final int count = router.getCategoryCount(); 6024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown List out = new ArrayList(count); 6124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown for (int i = 0; i < count; i++) { 6224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown out.add(router.getCategoryAt(i)); 6324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 6424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return out; 6524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 6624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 6724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static Object getSelectedRoute(Object routerObj, int type) { 6824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter)routerObj).getSelectedRoute(type); 6924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 7024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 7124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void selectRoute(Object routerObj, int types, Object routeObj) { 7224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter)routerObj).selectRoute(types, 7324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown (android.media.MediaRouter.RouteInfo)routeObj); 7424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 7524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 7624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void addCallback(Object routerObj, int types, Object callbackObj) { 7724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter)routerObj).addCallback(types, 7824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown (android.media.MediaRouter.Callback)callbackObj); 7924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 8024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 8124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void removeCallback(Object routerObj, Object callbackObj) { 8224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter)routerObj).removeCallback( 8324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown (android.media.MediaRouter.Callback)callbackObj); 8424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 8524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 8624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static Object createRouteCategory(Object routerObj, 8724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown String name, boolean isGroupable) { 8824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter)routerObj).createRouteCategory(name, isGroupable); 8924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 9024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 9124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static Object createUserRoute(Object routerObj, Object categoryObj) { 9224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter)routerObj).createUserRoute( 9324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown (android.media.MediaRouter.RouteCategory)categoryObj); 9424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 9524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 9624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void addUserRoute(Object routerObj, Object routeObj) { 9724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter)routerObj).addUserRoute( 9824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown (android.media.MediaRouter.UserRouteInfo)routeObj); 9924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 10024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 10124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void removeUserRoute(Object routerObj, Object routeObj) { 10224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter)routerObj).removeUserRoute( 10324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown (android.media.MediaRouter.UserRouteInfo)routeObj); 10424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 10524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 10624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static Object createCallback(Callback callback) { 10724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return new CallbackProxy<Callback>(callback); 10824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 10924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 11024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static Object createVolumeCallback(VolumeCallback callback) { 11124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return new VolumeCallbackProxy<VolumeCallback>(callback); 11224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 11324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 11424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static final class RouteInfo { 11524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static CharSequence getName(Object routeObj, Context context) { 11624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter.RouteInfo)routeObj).getName(context); 11724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 11824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 11924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static CharSequence getStatus(Object routeObj) { 12024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter.RouteInfo)routeObj).getStatus(); 12124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 12224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 12324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static int getSupportedTypes(Object routeObj) { 12424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter.RouteInfo)routeObj).getSupportedTypes(); 12524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 12624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 12724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static Object getCategory(Object routeObj) { 12824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter.RouteInfo)routeObj).getCategory(); 12924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 13024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 13124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static Drawable getIconDrawable(Object routeObj) { 13224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter.RouteInfo)routeObj).getIconDrawable(); 13324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 13424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 13524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static int getPlaybackType(Object routeObj) { 13624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter.RouteInfo)routeObj).getPlaybackType(); 13724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 13824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 13924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static int getPlaybackStream(Object routeObj) { 14024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter.RouteInfo)routeObj).getPlaybackStream(); 14124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 14224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 14324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static int getVolume(Object routeObj) { 14424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter.RouteInfo)routeObj).getVolume(); 14524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 14624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 14724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static int getVolumeMax(Object routeObj) { 14824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter.RouteInfo)routeObj).getVolumeMax(); 14924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 15024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 15124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static int getVolumeHandling(Object routeObj) { 15224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter.RouteInfo)routeObj).getVolumeHandling(); 15324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 15424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 15524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static Object getTag(Object routeObj) { 15624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter.RouteInfo)routeObj).getTag(); 15724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 15824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 15924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void setTag(Object routeObj, Object tag) { 16024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter.RouteInfo)routeObj).setTag(tag); 16124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 16224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 16324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void requestSetVolume(Object routeObj, int volume) { 16424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter.RouteInfo)routeObj).requestSetVolume(volume); 16524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 16624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 16724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void requestUpdateVolume(Object routeObj, int direction) { 16824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter.RouteInfo)routeObj).requestUpdateVolume(direction); 16924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 17024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 17124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static Object getGroup(Object routeObj) { 17224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter.RouteInfo)routeObj).getGroup(); 17324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 17424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 17524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static boolean isGroup(Object routeObj) { 17624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return routeObj instanceof android.media.MediaRouter.RouteGroup; 17724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 17824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 17924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 18024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static final class RouteGroup { 18124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @SuppressWarnings({ "rawtypes", "unchecked" }) 18224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static List getGroupedRoutes(Object groupObj) { 18324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown final android.media.MediaRouter.RouteGroup group = 18424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown (android.media.MediaRouter.RouteGroup)groupObj; 18524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown final int count = group.getRouteCount(); 18624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown List out = new ArrayList(count); 18724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown for (int i = 0; i < count; i++) { 18824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown out.add(group.getRouteAt(i)); 18924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 19024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return out; 19124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 19224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 19324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 19424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static final class UserRouteInfo { 19524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void setName(Object routeObj, CharSequence name) { 19624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter.UserRouteInfo)routeObj).setName(name); 19724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 19824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 19924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void setStatus(Object routeObj, CharSequence status) { 20024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter.UserRouteInfo)routeObj).setStatus(status); 20124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 20224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 20324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void setIconDrawable(Object routeObj, Drawable icon) { 20424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter.UserRouteInfo)routeObj).setIconDrawable(icon); 20524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 20624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 20724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void setPlaybackType(Object routeObj, int type) { 20824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter.UserRouteInfo)routeObj).setPlaybackType(type); 20924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 21024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 21124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void setPlaybackStream(Object routeObj, int stream) { 21224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter.UserRouteInfo)routeObj).setPlaybackStream(stream); 21324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 21424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 21524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void setVolume(Object routeObj, int volume) { 21624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter.UserRouteInfo)routeObj).setVolume(volume); 21724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 21824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 21924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void setVolumeMax(Object routeObj, int volumeMax) { 22024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter.UserRouteInfo)routeObj).setVolumeMax(volumeMax); 22124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 22224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 22324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void setVolumeHandling(Object routeObj, int volumeHandling) { 22424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter.UserRouteInfo)routeObj).setVolumeHandling(volumeHandling); 22524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 22624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 22724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void setVolumeCallback(Object routeObj, Object volumeCallbackObj) { 22824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter.UserRouteInfo)routeObj).setVolumeCallback( 22924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown (android.media.MediaRouter.VolumeCallback)volumeCallbackObj); 23024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 23124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 23224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static void setRemoteControlClient(Object routeObj, Object rccObj) { 23324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter.UserRouteInfo)routeObj).setRemoteControlClient( 23424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown (android.media.RemoteControlClient)rccObj); 23524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 23624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 23724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 23824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static final class RouteCategory { 23924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static CharSequence getName(Object categoryObj, Context context) { 24024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter.RouteCategory)categoryObj).getName(context); 24124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 24224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 24324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @SuppressWarnings({ "rawtypes", "unchecked" }) 24424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static List getRoutes(Object categoryObj) { 24524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ArrayList out = new ArrayList(); 24624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown ((android.media.MediaRouter.RouteCategory)categoryObj).getRoutes(out); 24724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return out; 24824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 24924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 25024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static int getSupportedTypes(Object categoryObj) { 25124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter.RouteCategory)categoryObj).getSupportedTypes(); 25224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 25324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 25424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static boolean isGroupable(Object categoryObj) { 25524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return ((android.media.MediaRouter.RouteCategory)categoryObj).isGroupable(); 25624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 25724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 25824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 25924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static interface Callback { 26024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onRouteSelected(int type, Object routeObj); 26124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onRouteUnselected(int type, Object routeObj); 26224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onRouteAdded(Object routeObj); 26324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onRouteRemoved(Object routeObj); 26424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onRouteChanged(Object routeObj); 26524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onRouteGrouped(Object routeObj, Object groupObj, int index); 26624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onRouteUngrouped(Object routeObj, Object groupObj); 26724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onRouteVolumeChanged(Object routeObj); 26824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 26924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 27024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static interface VolumeCallback { 27124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onVolumeSetRequest(Object routeObj, int volume); 27224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onVolumeUpdateRequest(Object routeObj, int direction); 27324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 27424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 27524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 27624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Workaround for limitations of selectRoute() on JB and JB MR1. 27724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Do not use on JB MR2 and above. 27824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 27924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static final class SelectRouteWorkaround { 28024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private Method mSelectRouteIntMethod; 28124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 28224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public SelectRouteWorkaround() { 28324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (Build.VERSION.SDK_INT < 16 || Build.VERSION.SDK_INT > 17) { 28424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new UnsupportedOperationException(); 28524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 28624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown try { 28724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mSelectRouteIntMethod = android.media.MediaRouter.class.getMethod( 28824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown "selectRouteInt", int.class, android.media.MediaRouter.RouteInfo.class); 28924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } catch (NoSuchMethodException ex) { 29024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 29124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 29224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 29324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void selectRoute(Object routerObj, int types, Object routeObj) { 29424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown android.media.MediaRouter router = (android.media.MediaRouter)routerObj; 29524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown android.media.MediaRouter.RouteInfo route = 29624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown (android.media.MediaRouter.RouteInfo)routeObj; 29724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 29824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown int routeTypes = route.getSupportedTypes(); 29924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if ((routeTypes & ROUTE_TYPE_USER) == 0) { 30024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown // Handle non-user routes. 30124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown // On JB and JB MR1, the selectRoute() API only supports programmatically 30224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown // selecting user routes. So instead we rely on the hidden selectRouteInt() 30324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown // method on these versions of the platform. 30424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown // This limitation was removed in JB MR2. 30524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (mSelectRouteIntMethod != null) { 30624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown try { 30724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mSelectRouteIntMethod.invoke(router, types, route); 30824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return; // success! 30924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } catch (IllegalAccessException ex) { 31024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Log.w(TAG, "Cannot programmatically select non-user route. " 31124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown + "Media routing may not work.", ex); 31224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } catch (InvocationTargetException ex) { 31324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Log.w(TAG, "Cannot programmatically select non-user route. " 31424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown + "Media routing may not work.", ex); 31524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 31624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } else { 31724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown Log.w(TAG, "Cannot programmatically select non-user route " 31824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown + "because the platform is missing the selectRouteInt() " 31924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown + "method. Media routing may not work."); 32024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 32124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 32224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 32324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown // Default handling. 32424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown router.selectRoute(types, route); 32524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 32624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 32724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 32824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown /** 32924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Workaround the fact that the getDefaultRoute() method does not exist in JB and JB MR1. 33024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown * Do not use on JB MR2 and above. 33124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown */ 33224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public static final class GetDefaultRouteWorkaround { 33324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown private Method mGetSystemAudioRouteMethod; 33424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 33524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public GetDefaultRouteWorkaround() { 33624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (Build.VERSION.SDK_INT < 16 || Build.VERSION.SDK_INT > 17) { 33724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown throw new UnsupportedOperationException(); 33824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 33924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown try { 34024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mGetSystemAudioRouteMethod = 34124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown android.media.MediaRouter.class.getMethod("getSystemAudioRoute"); 34224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } catch (NoSuchMethodException ex) { 34324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 34424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 34524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 34624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public Object getDefaultRoute(Object routerObj) { 34724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown android.media.MediaRouter router = (android.media.MediaRouter)routerObj; 34824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 34924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown if (mGetSystemAudioRouteMethod != null) { 35024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown try { 35124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return mGetSystemAudioRouteMethod.invoke(router); 35224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } catch (IllegalAccessException ex) { 35324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } catch (InvocationTargetException ex) { 35424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 35524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 35624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 35724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown // Could not find the method or it does not work. 35824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown // Return the first route and hope for the best. 35924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown return router.getRouteAt(0); 36024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 36124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 36224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 36324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown static class CallbackProxy<T extends Callback> 36424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown extends android.media.MediaRouter.Callback { 36524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown protected final T mCallback; 36624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 36724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public CallbackProxy(T callback) { 36824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCallback = callback; 36924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 37024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 37124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 37224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onRouteSelected(android.media.MediaRouter router, 37324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown int type, android.media.MediaRouter.RouteInfo route) { 37424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCallback.onRouteSelected(type, route); 37524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 37624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 37724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 37824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onRouteUnselected(android.media.MediaRouter router, 37924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown int type, android.media.MediaRouter.RouteInfo route) { 38024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCallback.onRouteUnselected(type, route); 38124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 38224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 38324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 38424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onRouteAdded(android.media.MediaRouter router, 38524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown android.media.MediaRouter.RouteInfo route) { 38624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCallback.onRouteAdded(route); 38724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 38824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 38924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 39024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onRouteRemoved(android.media.MediaRouter router, 39124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown android.media.MediaRouter.RouteInfo route) { 39224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCallback.onRouteRemoved(route); 39324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 39424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 39524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 39624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onRouteChanged(android.media.MediaRouter router, 39724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown android.media.MediaRouter.RouteInfo route) { 39824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCallback.onRouteChanged(route); 39924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 40024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 40124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 40224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onRouteGrouped(android.media.MediaRouter router, 40324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown android.media.MediaRouter.RouteInfo route, 40424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown android.media.MediaRouter.RouteGroup group, int index) { 40524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCallback.onRouteGrouped(route, group, index); 40624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 40724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 40824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 40924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onRouteUngrouped(android.media.MediaRouter router, 41024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown android.media.MediaRouter.RouteInfo route, 41124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown android.media.MediaRouter.RouteGroup group) { 41224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCallback.onRouteUngrouped(route, group); 41324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 41424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 41524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 41624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onRouteVolumeChanged(android.media.MediaRouter router, 41724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown android.media.MediaRouter.RouteInfo route) { 41824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCallback.onRouteVolumeChanged(route); 41924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 42024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 42124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 42224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown static class VolumeCallbackProxy<T extends VolumeCallback> 42324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown extends android.media.MediaRouter.VolumeCallback { 42424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown protected final T mCallback; 42524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 42624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public VolumeCallbackProxy(T callback) { 42724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCallback = callback; 42824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 42924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 43024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 43124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onVolumeSetRequest(android.media.MediaRouter.RouteInfo route, 43224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown int volume) { 43324fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCallback.onVolumeSetRequest(route, volume); 43424fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 43524fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown 43624fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown @Override 43724fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown public void onVolumeUpdateRequest(android.media.MediaRouter.RouteInfo route, 43824fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown int direction) { 43924fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown mCallback.onVolumeUpdateRequest(route, direction); 44024fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 44124fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown } 44224fa6c0dd42df057729e1a258388183f94da7f82Jeff Brown} 443