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