MediaRouter.java revision 1357012968f9066ea3051d83995e9bac69526c3c
19a1de308cea2d160778fd977825f10a07b49d738Adam Powell/* 29a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Copyright (C) 2012 The Android Open Source Project 39a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 49a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Licensed under the Apache License, Version 2.0 (the "License"); 59a1de308cea2d160778fd977825f10a07b49d738Adam Powell * you may not use this file except in compliance with the License. 69a1de308cea2d160778fd977825f10a07b49d738Adam Powell * You may obtain a copy of the License at 79a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 89a1de308cea2d160778fd977825f10a07b49d738Adam Powell * http://www.apache.org/licenses/LICENSE-2.0 99a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 109a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Unless required by applicable law or agreed to in writing, software 119a1de308cea2d160778fd977825f10a07b49d738Adam Powell * distributed under the License is distributed on an "AS IS" BASIS, 129a1de308cea2d160778fd977825f10a07b49d738Adam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139a1de308cea2d160778fd977825f10a07b49d738Adam Powell * See the License for the specific language governing permissions and 149a1de308cea2d160778fd977825f10a07b49d738Adam Powell * limitations under the License. 159a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 169a1de308cea2d160778fd977825f10a07b49d738Adam Powell 179a1de308cea2d160778fd977825f10a07b49d738Adam Powellpackage android.media; 189a1de308cea2d160778fd977825f10a07b49d738Adam Powell 199a1de308cea2d160778fd977825f10a07b49d738Adam Powellimport android.content.Context; 20b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackbornimport android.content.res.Resources; 21ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powellimport android.graphics.drawable.Drawable; 229a1de308cea2d160778fd977825f10a07b49d738Adam Powellimport android.os.Handler; 23632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackbornimport android.os.IBinder; 24632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackbornimport android.os.RemoteException; 25632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackbornimport android.os.ServiceManager; 26632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackbornimport android.text.TextUtils; 279a1de308cea2d160778fd977825f10a07b49d738Adam Powellimport android.util.Log; 289a1de308cea2d160778fd977825f10a07b49d738Adam Powell 299a1de308cea2d160778fd977825f10a07b49d738Adam Powellimport java.util.ArrayList; 309a1de308cea2d160778fd977825f10a07b49d738Adam Powellimport java.util.HashMap; 31d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powellimport java.util.List; 3239d5c6172503620ac3761148adac5fd7fa20d02dAdam Powellimport java.util.concurrent.CopyOnWriteArrayList; 339a1de308cea2d160778fd977825f10a07b49d738Adam Powell 349a1de308cea2d160778fd977825f10a07b49d738Adam Powell/** 359a1de308cea2d160778fd977825f10a07b49d738Adam Powell * MediaRouter allows applications to control the routing of media channels 369a1de308cea2d160778fd977825f10a07b49d738Adam Powell * and streams from the current device to external speakers and destination devices. 379a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 38b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn * <p>A MediaRouter is retrieved through {@link Context#getSystemService(String) 39b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn * Context.getSystemService()} of a {@link Context#MEDIA_ROUTER_SERVICE 40b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn * Context.MEDIA_ROUTER_SERVICE}. 41b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn * 42b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn * <p>The media router API is not thread-safe; all interactions with it must be 43b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn * done from the main thread of the process.</p> 449a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 459a1de308cea2d160778fd977825f10a07b49d738Adam Powellpublic class MediaRouter { 469a1de308cea2d160778fd977825f10a07b49d738Adam Powell private static final String TAG = "MediaRouter"; 479a1de308cea2d160778fd977825f10a07b49d738Adam Powell 48b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn static class Static { 49b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell final Resources mResources; 50632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn final IAudioService mAudioService; 51b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell final Handler mHandler; 5239d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell final CopyOnWriteArrayList<CallbackInfo> mCallbacks = 5339d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell new CopyOnWriteArrayList<CallbackInfo>(); 54b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn 55b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell final ArrayList<RouteInfo> mRoutes = new ArrayList<RouteInfo>(); 56b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell final ArrayList<RouteCategory> mCategories = new ArrayList<RouteCategory>(); 57b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn 58b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell final RouteCategory mSystemCategory; 59632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn 60632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn final AudioRoutesInfo mCurRoutesInfo = new AudioRoutesInfo(); 61b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn 62b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell RouteInfo mDefaultAudio; 63b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell RouteInfo mBluetoothA2dpRoute; 64b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn 65b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell RouteInfo mSelectedRoute; 669a1de308cea2d160778fd977825f10a07b49d738Adam Powell 67632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn final IAudioRoutesObserver.Stub mRoutesObserver = new IAudioRoutesObserver.Stub() { 68632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn public void dispatchAudioRoutesChanged(final AudioRoutesInfo newRoutes) { 69632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn mHandler.post(new Runnable() { 70632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn @Override public void run() { 71632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn updateRoutes(newRoutes); 72632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn } 73632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn }); 74632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn } 75632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn }; 76632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn 77b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn Static(Context appContext) { 78b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn mResources = Resources.getSystem(); 79b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn mHandler = new Handler(appContext.getMainLooper()); 809a1de308cea2d160778fd977825f10a07b49d738Adam Powell 81632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE); 82632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn mAudioService = IAudioService.Stub.asInterface(b); 839a1de308cea2d160778fd977825f10a07b49d738Adam Powell 84dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell mSystemCategory = new RouteCategory( 85dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell com.android.internal.R.string.default_audio_route_category_name, 86b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn ROUTE_TYPE_LIVE_AUDIO, false); 87b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell } 88b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn 89b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell // Called after sStatic is initialized 90632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn void startMonitoringRoutes() { 91b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn mDefaultAudio = new RouteInfo(mSystemCategory); 920d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell mDefaultAudio.mNameResId = com.android.internal.R.string.default_audio_route_name; 93b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn mDefaultAudio.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO; 94b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn addRoute(mDefaultAudio); 95632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn 96632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn AudioRoutesInfo newRoutes = null; 97632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn try { 98632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn newRoutes = mAudioService.startWatchingRoutes(mRoutesObserver); 99632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn } catch (RemoteException e) { 100632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn } 101632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn if (newRoutes != null) { 102632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn updateRoutes(newRoutes); 103632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn } 104632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn } 105632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn 106632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn void updateRoutes(AudioRoutesInfo newRoutes) { 107632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn if (newRoutes.mMainType != mCurRoutesInfo.mMainType) { 108632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn mCurRoutesInfo.mMainType = newRoutes.mMainType; 109632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn int name; 110632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_HEADPHONES) != 0 111632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn || (newRoutes.mMainType&AudioRoutesInfo.MAIN_HEADSET) != 0) { 112632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn name = com.android.internal.R.string.default_audio_route_name_headphones; 113632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn } else if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_DOCK_SPEAKERS) != 0) { 114632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn name = com.android.internal.R.string.default_audio_route_name_dock_speakers; 115632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn } else if ((newRoutes.mMainType&AudioRoutesInfo.MAIN_HDMI) != 0) { 116632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn name = com.android.internal.R.string.default_audio_route_name_hdmi; 117632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn } else { 118632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn name = com.android.internal.R.string.default_audio_route_name; 119632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn } 120632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn sStatic.mDefaultAudio.mNameResId = name; 121632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn dispatchRouteChanged(sStatic.mDefaultAudio); 122632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn } 123632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn if (!TextUtils.equals(newRoutes.mBluetoothName, mCurRoutesInfo.mBluetoothName)) { 124632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn mCurRoutesInfo.mBluetoothName = newRoutes.mBluetoothName; 125632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn if (mCurRoutesInfo.mBluetoothName != null) { 126632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn if (sStatic.mBluetoothA2dpRoute == null) { 127632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn final RouteInfo info = new RouteInfo(sStatic.mSystemCategory); 128632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn info.mName = mCurRoutesInfo.mBluetoothName; 129632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn info.mSupportedTypes = ROUTE_TYPE_LIVE_AUDIO; 130632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn sStatic.mBluetoothA2dpRoute = info; 131632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn addRoute(sStatic.mBluetoothA2dpRoute); 132dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell try { 133dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell if (mAudioService.isBluetoothA2dpOn()) { 134dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO, mBluetoothA2dpRoute); 135dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell } 136dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell } catch (RemoteException e) { 137dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell Log.e(TAG, "Error selecting Bluetooth A2DP route", e); 138dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell } 139632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn } else { 140632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn sStatic.mBluetoothA2dpRoute.mName = mCurRoutesInfo.mBluetoothName; 141632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn dispatchRouteChanged(sStatic.mBluetoothA2dpRoute); 142632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn } 143632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn } else if (sStatic.mBluetoothA2dpRoute != null) { 144632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn removeRoute(sStatic.mBluetoothA2dpRoute); 145632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn sStatic.mBluetoothA2dpRoute = null; 146632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn } 147632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn } 148b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn } 149b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn } 1509a1de308cea2d160778fd977825f10a07b49d738Adam Powell 151b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn static Static sStatic; 1529a1de308cea2d160778fd977825f10a07b49d738Adam Powell 1539a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 1549a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Route type flag for live audio. 1559a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 1569a1de308cea2d160778fd977825f10a07b49d738Adam Powell * <p>A device that supports live audio routing will allow the media audio stream 1579a1de308cea2d160778fd977825f10a07b49d738Adam Powell * to be routed to supported destinations. This can include internal speakers or 1589a1de308cea2d160778fd977825f10a07b49d738Adam Powell * audio jacks on the device itself, A2DP devices, and more.</p> 1599a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 1609a1de308cea2d160778fd977825f10a07b49d738Adam Powell * <p>Once initiated this routing is transparent to the application. All audio 1619a1de308cea2d160778fd977825f10a07b49d738Adam Powell * played on the media stream will be routed to the selected destination.</p> 1629a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 1639a1de308cea2d160778fd977825f10a07b49d738Adam Powell public static final int ROUTE_TYPE_LIVE_AUDIO = 0x1; 1649a1de308cea2d160778fd977825f10a07b49d738Adam Powell 1659a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 1669a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Route type flag for application-specific usage. 1679a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 1689a1de308cea2d160778fd977825f10a07b49d738Adam Powell * <p>Unlike other media route types, user routes are managed by the application. 1699a1de308cea2d160778fd977825f10a07b49d738Adam Powell * The MediaRouter will manage and dispatch events for user routes, but the application 1709a1de308cea2d160778fd977825f10a07b49d738Adam Powell * is expected to interpret the meaning of these events and perform the requested 1719a1de308cea2d160778fd977825f10a07b49d738Adam Powell * routing tasks.</p> 1729a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 1739a1de308cea2d160778fd977825f10a07b49d738Adam Powell public static final int ROUTE_TYPE_USER = 0x00800000; 1749a1de308cea2d160778fd977825f10a07b49d738Adam Powell 1759a1de308cea2d160778fd977825f10a07b49d738Adam Powell // Maps application contexts 1769a1de308cea2d160778fd977825f10a07b49d738Adam Powell static final HashMap<Context, MediaRouter> sRouters = new HashMap<Context, MediaRouter>(); 1779a1de308cea2d160778fd977825f10a07b49d738Adam Powell 1789a1de308cea2d160778fd977825f10a07b49d738Adam Powell static String typesToString(int types) { 1799a1de308cea2d160778fd977825f10a07b49d738Adam Powell final StringBuilder result = new StringBuilder(); 1809a1de308cea2d160778fd977825f10a07b49d738Adam Powell if ((types & ROUTE_TYPE_LIVE_AUDIO) != 0) { 1819a1de308cea2d160778fd977825f10a07b49d738Adam Powell result.append("ROUTE_TYPE_LIVE_AUDIO "); 1829a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 1839a1de308cea2d160778fd977825f10a07b49d738Adam Powell if ((types & ROUTE_TYPE_USER) != 0) { 1849a1de308cea2d160778fd977825f10a07b49d738Adam Powell result.append("ROUTE_TYPE_USER "); 1859a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 1869a1de308cea2d160778fd977825f10a07b49d738Adam Powell return result.toString(); 1879a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 1889a1de308cea2d160778fd977825f10a07b49d738Adam Powell 189b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn /** @hide */ 190b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn public MediaRouter(Context context) { 191b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn synchronized (Static.class) { 192b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn if (sStatic == null) { 193b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn sStatic = new Static(context.getApplicationContext()); 194632ca417f0a33e3fa9ccece531afa2db3f0d4a30Dianne Hackborn sStatic.startMonitoringRoutes(); 195b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn } 1969a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 1979a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 1989a1de308cea2d160778fd977825f10a07b49d738Adam Powell 199690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell /** 200690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * @hide for use by framework routing UI 201690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell */ 202690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public RouteInfo getSystemAudioRoute() { 203b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn return sStatic.mDefaultAudio; 204690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 205690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 206690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell /** 2074599696591f745b3a546197d2ba7e5cfc5562484Adam Powell * @hide for use by framework routing UI 2084599696591f745b3a546197d2ba7e5cfc5562484Adam Powell */ 2094599696591f745b3a546197d2ba7e5cfc5562484Adam Powell public RouteCategory getSystemAudioCategory() { 2104599696591f745b3a546197d2ba7e5cfc5562484Adam Powell return sStatic.mSystemCategory; 2114599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 2124599696591f745b3a546197d2ba7e5cfc5562484Adam Powell 2134599696591f745b3a546197d2ba7e5cfc5562484Adam Powell /** 214690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * Return the currently selected route for the given types 215690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * 216690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * @param type route types 217690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * @return the selected route 218690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell */ 219690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public RouteInfo getSelectedRoute(int type) { 220b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn return sStatic.mSelectedRoute; 221690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 222690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 2239a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 2249a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Add a callback to listen to events about specific kinds of media routes. 2259a1de308cea2d160778fd977825f10a07b49d738Adam Powell * If the specified callback is already registered, its registration will be updated for any 2269a1de308cea2d160778fd977825f10a07b49d738Adam Powell * additional route types specified. 2279a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 2289a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param types Types of routes this callback is interested in 2299a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param cb Callback to add 2309a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 2319a1de308cea2d160778fd977825f10a07b49d738Adam Powell public void addCallback(int types, Callback cb) { 232b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn final int count = sStatic.mCallbacks.size(); 2339a1de308cea2d160778fd977825f10a07b49d738Adam Powell for (int i = 0; i < count; i++) { 234b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn final CallbackInfo info = sStatic.mCallbacks.get(i); 2359a1de308cea2d160778fd977825f10a07b49d738Adam Powell if (info.cb == cb) { 2369a1de308cea2d160778fd977825f10a07b49d738Adam Powell info.type &= types; 2379a1de308cea2d160778fd977825f10a07b49d738Adam Powell return; 2389a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 2399a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 240b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn sStatic.mCallbacks.add(new CallbackInfo(cb, types, this)); 2419a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 2429a1de308cea2d160778fd977825f10a07b49d738Adam Powell 2439a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 2449a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Remove the specified callback. It will no longer receive events about media routing. 2459a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 2469a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param cb Callback to remove 2479a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 2489a1de308cea2d160778fd977825f10a07b49d738Adam Powell public void removeCallback(Callback cb) { 249b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn final int count = sStatic.mCallbacks.size(); 2509a1de308cea2d160778fd977825f10a07b49d738Adam Powell for (int i = 0; i < count; i++) { 251b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn if (sStatic.mCallbacks.get(i).cb == cb) { 252b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn sStatic.mCallbacks.remove(i); 2539a1de308cea2d160778fd977825f10a07b49d738Adam Powell return; 2549a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 2559a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 2569a1de308cea2d160778fd977825f10a07b49d738Adam Powell Log.w(TAG, "removeCallback(" + cb + "): callback not registered"); 2579a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 2589a1de308cea2d160778fd977825f10a07b49d738Adam Powell 259d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell /** 260d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * Select the specified route to use for output of the given media types. 261d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * 262d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @param types type flags indicating which types this route should be used for. 263d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * The route must support at least a subset. 264d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @param route Route to select 265d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell */ 2669a1de308cea2d160778fd977825f10a07b49d738Adam Powell public void selectRoute(int types, RouteInfo route) { 2670d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell // Applications shouldn't programmatically change anything but user routes. 2680d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell types &= ROUTE_TYPE_USER; 2690d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell selectRouteStatic(types, route); 2700d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell } 2710d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell 2720d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell /** 2730d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * @hide internal use 2740d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell */ 2750d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell public void selectRouteInt(int types, RouteInfo route) { 276b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn selectRouteStatic(types, route); 277b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn } 278b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn 279b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn static void selectRouteStatic(int types, RouteInfo route) { 280b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn if (sStatic.mSelectedRoute == route) return; 2810d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell if ((route.getSupportedTypes() & types) == 0) { 2820d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell Log.w(TAG, "selectRoute ignored; cannot select route with supported types " + 2830d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell typesToString(route.getSupportedTypes()) + " into route types " + 2840d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell typesToString(types)); 2854ee1f55ce0f4909a7430ab44563a81852f335071Adam Powell return; 2860d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell } 2879a1de308cea2d160778fd977825f10a07b49d738Adam Powell 288dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell final RouteInfo btRoute = sStatic.mBluetoothA2dpRoute; 289dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell if (btRoute != null && (types & ROUTE_TYPE_LIVE_AUDIO) != 0 && 290dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell (route == btRoute || route == sStatic.mDefaultAudio)) { 291dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell try { 292dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell sStatic.mAudioService.setBluetoothA2dpOn(route == btRoute); 293dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell } catch (RemoteException e) { 294dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell Log.e(TAG, "Error changing Bluetooth A2DP state", e); 295dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell } 296dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell } 297dd0a19266d5c837069da1ea188744d54c8d723a8Adam Powell 298b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn if (sStatic.mSelectedRoute != null) { 2999a1de308cea2d160778fd977825f10a07b49d738Adam Powell // TODO filter types properly 300b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn dispatchRouteUnselected(types & sStatic.mSelectedRoute.getSupportedTypes(), 301b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn sStatic.mSelectedRoute); 3029a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 303b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn sStatic.mSelectedRoute = route; 3049a1de308cea2d160778fd977825f10a07b49d738Adam Powell if (route != null) { 3059a1de308cea2d160778fd977825f10a07b49d738Adam Powell // TODO filter types properly 3069a1de308cea2d160778fd977825f10a07b49d738Adam Powell dispatchRouteSelected(types & route.getSupportedTypes(), route); 3079a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 3089a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 3099a1de308cea2d160778fd977825f10a07b49d738Adam Powell 3109a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 3119a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Add an app-specified route for media to the MediaRouter. 3129a1de308cea2d160778fd977825f10a07b49d738Adam Powell * App-specified route definitions are created using {@link #createUserRoute(RouteCategory)} 3139a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 3149a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param info Definition of the route to add 3159a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @see #createUserRoute() 3169a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @see #removeUserRoute(UserRouteInfo) 3179a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 3189a1de308cea2d160778fd977825f10a07b49d738Adam Powell public void addUserRoute(UserRouteInfo info) { 3199a1de308cea2d160778fd977825f10a07b49d738Adam Powell addRoute(info); 3209a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 3219a1de308cea2d160778fd977825f10a07b49d738Adam Powell 322d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell /** 323d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell * @hide Framework use only 324d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell */ 325d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell public void addRouteInt(RouteInfo info) { 326d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell addRoute(info); 327d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 328d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell 329b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn static void addRoute(RouteInfo info) { 3309a1de308cea2d160778fd977825f10a07b49d738Adam Powell final RouteCategory cat = info.getCategory(); 331b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn if (!sStatic.mCategories.contains(cat)) { 332b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn sStatic.mCategories.add(cat); 3339a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 334b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn final boolean onlyRoute = sStatic.mRoutes.isEmpty(); 335d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell if (cat.isGroupable() && !(info instanceof RouteGroup)) { 3369a1de308cea2d160778fd977825f10a07b49d738Adam Powell // Enforce that any added route in a groupable category must be in a group. 3379a1de308cea2d160778fd977825f10a07b49d738Adam Powell final RouteGroup group = new RouteGroup(info.getCategory()); 338b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn sStatic.mRoutes.add(group); 339d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell dispatchRouteAdded(group); 340b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell group.addRoute(info); 341d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell 3429a1de308cea2d160778fd977825f10a07b49d738Adam Powell info = group; 343d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell } else { 344b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn sStatic.mRoutes.add(info); 345d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell dispatchRouteAdded(info); 3469a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 347d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell 3489a1de308cea2d160778fd977825f10a07b49d738Adam Powell if (onlyRoute) { 349b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn selectRouteStatic(info.getSupportedTypes(), info); 3509a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 3519a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 3529a1de308cea2d160778fd977825f10a07b49d738Adam Powell 3539a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 3549a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Remove an app-specified route for media from the MediaRouter. 3559a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 3569a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param info Definition of the route to remove 3579a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @see #addUserRoute(UserRouteInfo) 3589a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 3599a1de308cea2d160778fd977825f10a07b49d738Adam Powell public void removeUserRoute(UserRouteInfo info) { 3609a1de308cea2d160778fd977825f10a07b49d738Adam Powell removeRoute(info); 3619a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 3629a1de308cea2d160778fd977825f10a07b49d738Adam Powell 363690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell /** 364690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * Remove all app-specified routes from the MediaRouter. 365690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * 366690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * @see #removeUserRoute(UserRouteInfo) 367690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell */ 368690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public void clearUserRoutes() { 369b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn for (int i = 0; i < sStatic.mRoutes.size(); i++) { 370b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn final RouteInfo info = sStatic.mRoutes.get(i); 371d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell // TODO Right now, RouteGroups only ever contain user routes. 372d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell // The code below will need to change if this assumption does. 373d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell if (info instanceof UserRouteInfo || info instanceof RouteGroup) { 374690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell removeRouteAt(i); 375690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell i--; 376690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 377690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 378690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 379690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 380d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell /** 381d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell * @hide internal use only 382d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell */ 383d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell public void removeRouteInt(RouteInfo info) { 384d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell removeRoute(info); 385d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 386d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell 387b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn static void removeRoute(RouteInfo info) { 388b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn if (sStatic.mRoutes.remove(info)) { 3899a1de308cea2d160778fd977825f10a07b49d738Adam Powell final RouteCategory removingCat = info.getCategory(); 390b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn final int count = sStatic.mRoutes.size(); 3919a1de308cea2d160778fd977825f10a07b49d738Adam Powell boolean found = false; 3929a1de308cea2d160778fd977825f10a07b49d738Adam Powell for (int i = 0; i < count; i++) { 393b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn final RouteCategory cat = sStatic.mRoutes.get(i).getCategory(); 3949a1de308cea2d160778fd977825f10a07b49d738Adam Powell if (removingCat == cat) { 3959a1de308cea2d160778fd977825f10a07b49d738Adam Powell found = true; 3969a1de308cea2d160778fd977825f10a07b49d738Adam Powell break; 3979a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 3989a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 399d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell if (info == sStatic.mSelectedRoute) { 400d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell // Removing the currently selected route? Select the default before we remove it. 401d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell // TODO: Be smarter about the route types here; this selects for all valid. 402d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_USER, sStatic.mDefaultAudio); 403d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 4049a1de308cea2d160778fd977825f10a07b49d738Adam Powell if (!found) { 405b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn sStatic.mCategories.remove(removingCat); 4069a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 4079a1de308cea2d160778fd977825f10a07b49d738Adam Powell dispatchRouteRemoved(info); 4089a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 4099a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 4109a1de308cea2d160778fd977825f10a07b49d738Adam Powell 411690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell void removeRouteAt(int routeIndex) { 412b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn if (routeIndex >= 0 && routeIndex < sStatic.mRoutes.size()) { 413b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn final RouteInfo info = sStatic.mRoutes.remove(routeIndex); 414690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final RouteCategory removingCat = info.getCategory(); 415b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn final int count = sStatic.mRoutes.size(); 416690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell boolean found = false; 417690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell for (int i = 0; i < count; i++) { 418b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn final RouteCategory cat = sStatic.mRoutes.get(i).getCategory(); 419690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (removingCat == cat) { 420690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell found = true; 421690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell break; 422690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 423690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 424d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell if (info == sStatic.mSelectedRoute) { 425d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell // Removing the currently selected route? Select the default before we remove it. 426d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell // TODO: Be smarter about the route types here; this selects for all valid. 427d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell selectRouteStatic(ROUTE_TYPE_LIVE_AUDIO | ROUTE_TYPE_USER, sStatic.mDefaultAudio); 428d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 429690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (!found) { 430b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn sStatic.mCategories.remove(removingCat); 431690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 432690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell dispatchRouteRemoved(info); 433690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 434690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 435690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 4369a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 4379a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Return the number of {@link MediaRouter.RouteCategory categories} currently 4389a1de308cea2d160778fd977825f10a07b49d738Adam Powell * represented by routes known to this MediaRouter. 4399a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 4409a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @return the number of unique categories represented by this MediaRouter's known routes 4419a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 4429a1de308cea2d160778fd977825f10a07b49d738Adam Powell public int getCategoryCount() { 443b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn return sStatic.mCategories.size(); 4449a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 4459a1de308cea2d160778fd977825f10a07b49d738Adam Powell 4469a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 4479a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Return the {@link MediaRouter.RouteCategory category} at the given index. 4489a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Valid indices are in the range [0-getCategoryCount). 4499a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 4509a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param index which category to return 4519a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @return the category at index 4529a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 4539a1de308cea2d160778fd977825f10a07b49d738Adam Powell public RouteCategory getCategoryAt(int index) { 454b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn return sStatic.mCategories.get(index); 4559a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 4569a1de308cea2d160778fd977825f10a07b49d738Adam Powell 4579a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 4589a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Return the number of {@link MediaRouter.RouteInfo routes} currently known 4599a1de308cea2d160778fd977825f10a07b49d738Adam Powell * to this MediaRouter. 4609a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 4619a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @return the number of routes tracked by this router 4629a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 4639a1de308cea2d160778fd977825f10a07b49d738Adam Powell public int getRouteCount() { 464b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn return sStatic.mRoutes.size(); 4659a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 4669a1de308cea2d160778fd977825f10a07b49d738Adam Powell 4679a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 4689a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Return the route at the specified index. 4699a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 4709a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param index index of the route to return 4719a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @return the route at index 4729a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 4739a1de308cea2d160778fd977825f10a07b49d738Adam Powell public RouteInfo getRouteAt(int index) { 474b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn return sStatic.mRoutes.get(index); 475b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn } 476b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn 477b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn static int getRouteCountStatic() { 478b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn return sStatic.mRoutes.size(); 479b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn } 480b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn 481b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn static RouteInfo getRouteAtStatic(int index) { 482b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn return sStatic.mRoutes.get(index); 4839a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 4849a1de308cea2d160778fd977825f10a07b49d738Adam Powell 4859a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 4869a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Create a new user route that may be modified and registered for use by the application. 4879a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 4889a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param category The category the new route will belong to 4899a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @return A new UserRouteInfo for use by the application 4909a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 4919a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @see #addUserRoute(UserRouteInfo) 4929a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @see #removeUserRoute(UserRouteInfo) 4939a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @see #createRouteCategory(CharSequence) 4949a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 4959a1de308cea2d160778fd977825f10a07b49d738Adam Powell public UserRouteInfo createUserRoute(RouteCategory category) { 4969a1de308cea2d160778fd977825f10a07b49d738Adam Powell return new UserRouteInfo(category); 4979a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 4989a1de308cea2d160778fd977825f10a07b49d738Adam Powell 4999a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 5009a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Create a new route category. Each route must belong to a category. 5019a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 5029a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param name Name of the new category 5039a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param isGroupable true if routes in this category may be grouped with one another 5049a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @return the new RouteCategory 5059a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 5069a1de308cea2d160778fd977825f10a07b49d738Adam Powell public RouteCategory createRouteCategory(CharSequence name, boolean isGroupable) { 5079a1de308cea2d160778fd977825f10a07b49d738Adam Powell return new RouteCategory(name, ROUTE_TYPE_USER, isGroupable); 5089a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5090d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell 5100d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell /** 5110d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * Create a new route category. Each route must belong to a category. 5120d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * 5130d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * @param nameResId Resource ID of the name of the new category 5140d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * @param isGroupable true if routes in this category may be grouped with one another 5150d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * @return the new RouteCategory 5160d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell */ 5170d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell public RouteCategory createRouteCategory(int nameResId, boolean isGroupable) { 5180d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell return new RouteCategory(nameResId, ROUTE_TYPE_USER, isGroupable); 5190d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell } 5209a1de308cea2d160778fd977825f10a07b49d738Adam Powell 521b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn static void updateRoute(final RouteInfo info) { 5229a1de308cea2d160778fd977825f10a07b49d738Adam Powell dispatchRouteChanged(info); 5239a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5249a1de308cea2d160778fd977825f10a07b49d738Adam Powell 525b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn static void dispatchRouteSelected(int type, RouteInfo info) { 52639d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell for (CallbackInfo cbi : sStatic.mCallbacks) { 5279a1de308cea2d160778fd977825f10a07b49d738Adam Powell if ((cbi.type & type) != 0) { 528b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn cbi.cb.onRouteSelected(cbi.router, type, info); 5299a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5309a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5319a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5329a1de308cea2d160778fd977825f10a07b49d738Adam Powell 533b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn static void dispatchRouteUnselected(int type, RouteInfo info) { 53439d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell for (CallbackInfo cbi : sStatic.mCallbacks) { 5359a1de308cea2d160778fd977825f10a07b49d738Adam Powell if ((cbi.type & type) != 0) { 536b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn cbi.cb.onRouteUnselected(cbi.router, type, info); 5379a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5389a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5399a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5409a1de308cea2d160778fd977825f10a07b49d738Adam Powell 541b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn static void dispatchRouteChanged(RouteInfo info) { 54239d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell for (CallbackInfo cbi : sStatic.mCallbacks) { 5439a1de308cea2d160778fd977825f10a07b49d738Adam Powell if ((cbi.type & info.mSupportedTypes) != 0) { 544b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn cbi.cb.onRouteChanged(cbi.router, info); 5459a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5469a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5479a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5489a1de308cea2d160778fd977825f10a07b49d738Adam Powell 549b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn static void dispatchRouteAdded(RouteInfo info) { 55039d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell for (CallbackInfo cbi : sStatic.mCallbacks) { 5519a1de308cea2d160778fd977825f10a07b49d738Adam Powell if ((cbi.type & info.mSupportedTypes) != 0) { 552b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn cbi.cb.onRouteAdded(cbi.router, info); 5539a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5549a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5559a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5569a1de308cea2d160778fd977825f10a07b49d738Adam Powell 557b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn static void dispatchRouteRemoved(RouteInfo info) { 55839d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell for (CallbackInfo cbi : sStatic.mCallbacks) { 5599a1de308cea2d160778fd977825f10a07b49d738Adam Powell if ((cbi.type & info.mSupportedTypes) != 0) { 560b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn cbi.cb.onRouteRemoved(cbi.router, info); 5619a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5629a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5639a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5649a1de308cea2d160778fd977825f10a07b49d738Adam Powell 565b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn static void dispatchRouteGrouped(RouteInfo info, RouteGroup group, int index) { 56639d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell for (CallbackInfo cbi : sStatic.mCallbacks) { 567d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell if ((cbi.type & group.mSupportedTypes) != 0) { 568b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn cbi.cb.onRouteGrouped(cbi.router, info, group, index); 569d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell } 570d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell } 571d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell } 572d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell 573b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn static void dispatchRouteUngrouped(RouteInfo info, RouteGroup group) { 57439d5c6172503620ac3761148adac5fd7fa20d02dAdam Powell for (CallbackInfo cbi : sStatic.mCallbacks) { 575d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell if ((cbi.type & group.mSupportedTypes) != 0) { 576b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn cbi.cb.onRouteUngrouped(cbi.router, info, group); 5779a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5789a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5799a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 5809a1de308cea2d160778fd977825f10a07b49d738Adam Powell 5819a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 5829a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Information about a media route. 5839a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 584b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn public static class RouteInfo { 5859a1de308cea2d160778fd977825f10a07b49d738Adam Powell CharSequence mName; 5860d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell int mNameResId; 5879a1de308cea2d160778fd977825f10a07b49d738Adam Powell private CharSequence mStatus; 5889a1de308cea2d160778fd977825f10a07b49d738Adam Powell int mSupportedTypes; 5899a1de308cea2d160778fd977825f10a07b49d738Adam Powell RouteGroup mGroup; 5909a1de308cea2d160778fd977825f10a07b49d738Adam Powell final RouteCategory mCategory; 591ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell Drawable mIcon; 5921357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi // playback information 5931357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi int mPlaybackType = PLAYBACK_TYPE_LOCAL; 5941357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi int mVolumeMax = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME; 5951357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi int mVolume = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME; 5961357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi int mVolumeHandling = RemoteControlClient.DEFAULT_PLAYBACK_VOLUME_HANDLING; 5971357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi int mPlaybackStream = AudioManager.STREAM_MUSIC; 5981357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi VolumeCallbackInfo mVcb; 5999a1de308cea2d160778fd977825f10a07b49d738Adam Powell 600b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell private Object mTag; 601b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 6021357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 6031357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide (to be un-hidden) 6041357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * The default playback type, "local", indicating the presentation of the media is happening 6051357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * on the same device (e.g. a phone, a tablet) as where it is controlled from. 6061357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @see #setPlaybackType(int) 6071357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 6081357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public final static int PLAYBACK_TYPE_LOCAL = 0; 6091357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 6101357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide (to be un-hidden) 6111357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * A playback type indicating the presentation of the media is happening on 6121357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * a different device (i.e. the remote device) than where it is controlled from. 6131357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @see #setPlaybackType(int) 6141357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 6151357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public final static int PLAYBACK_TYPE_REMOTE = 1; 6161357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 6171357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide (to be un-hidden) 6181357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * Playback information indicating the playback volume is fixed, i.e. it cannot be 6191357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * controlled from this object. An example of fixed playback volume is a remote player, 6201357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * playing over HDMI where the user prefers to control the volume on the HDMI sink, rather 6211357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * than attenuate at the source. 6221357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @see #setVolumeHandling(int) 6231357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 6241357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public final static int PLAYBACK_VOLUME_FIXED = 0; 6251357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 6261357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide (to be un-hidden) 6271357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * Playback information indicating the playback volume is variable and can be controlled 6281357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * from this object. 6291357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 6301357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public final static int PLAYBACK_VOLUME_VARIABLE = 1; 6311357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 6329a1de308cea2d160778fd977825f10a07b49d738Adam Powell RouteInfo(RouteCategory category) { 6339a1de308cea2d160778fd977825f10a07b49d738Adam Powell mCategory = category; 6349a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 6359a1de308cea2d160778fd977825f10a07b49d738Adam Powell 6369a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 6379a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @return The user-friendly name of a media route. This is the string presented 6389a1de308cea2d160778fd977825f10a07b49d738Adam Powell * to users who may select this as the active route. 6399a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 6409a1de308cea2d160778fd977825f10a07b49d738Adam Powell public CharSequence getName() { 6410d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell return getName(sStatic.mResources); 6420d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell } 6430d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell 6440d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell /** 6450d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * Return the properly localized/resource selected name of this route. 6460d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * 6470d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * @param context Context used to resolve the correct configuration to load 6480d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * @return The user-friendly name of the media route. This is the string presented 6490d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * to users who may select this as the active route. 6500d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell */ 6510d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell public CharSequence getName(Context context) { 6520d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell return getName(context.getResources()); 6530d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell } 6540d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell 6550d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell CharSequence getName(Resources res) { 6560d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell if (mNameResId != 0) { 6570d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell return mName = res.getText(mNameResId); 6580d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell } 6599a1de308cea2d160778fd977825f10a07b49d738Adam Powell return mName; 6609a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 6619a1de308cea2d160778fd977825f10a07b49d738Adam Powell 6629a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 6639a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @return The user-friendly status for a media route. This may include a description 6649a1de308cea2d160778fd977825f10a07b49d738Adam Powell * of the currently playing media, if available. 6659a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 6669a1de308cea2d160778fd977825f10a07b49d738Adam Powell public CharSequence getStatus() { 6679a1de308cea2d160778fd977825f10a07b49d738Adam Powell return mStatus; 6689a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 6699a1de308cea2d160778fd977825f10a07b49d738Adam Powell 6709a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 6719a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @return A media type flag set describing which types this route supports. 6729a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 6739a1de308cea2d160778fd977825f10a07b49d738Adam Powell public int getSupportedTypes() { 6749a1de308cea2d160778fd977825f10a07b49d738Adam Powell return mSupportedTypes; 6759a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 6769a1de308cea2d160778fd977825f10a07b49d738Adam Powell 6779a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 6789a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @return The group that this route belongs to. 6799a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 6809a1de308cea2d160778fd977825f10a07b49d738Adam Powell public RouteGroup getGroup() { 6819a1de308cea2d160778fd977825f10a07b49d738Adam Powell return mGroup; 6829a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 6839a1de308cea2d160778fd977825f10a07b49d738Adam Powell 6849a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 6859a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @return the category this route belongs to. 6869a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 6879a1de308cea2d160778fd977825f10a07b49d738Adam Powell public RouteCategory getCategory() { 6889a1de308cea2d160778fd977825f10a07b49d738Adam Powell return mCategory; 6899a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 6909a1de308cea2d160778fd977825f10a07b49d738Adam Powell 691ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell /** 692ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * Get the icon representing this route. 693ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * This icon will be used in picker UIs if available. 694ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * 695ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * @return the icon representing this route or null if no icon is available 696ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell */ 697ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell public Drawable getIconDrawable() { 698ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell return mIcon; 699ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell } 700ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell 701b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell /** 702b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * Set an application-specific tag object for this route. 703b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * The application may use this to store arbitrary data associated with the 704b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * route for internal tracking. 705b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * 706b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * <p>Note that the lifespan of a route may be well past the lifespan of 707b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * an Activity or other Context; take care that objects you store here 708b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * will not keep more data in memory alive than you intend.</p> 709b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * 710b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * @param tag Arbitrary, app-specific data for this route to hold for later use 711b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell */ 712b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell public void setTag(Object tag) { 713b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell mTag = tag; 714130b4572d1f3df702e5b296a655d15a41f6d4c66Adam Powell routeUpdated(); 715b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 716b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 717b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell /** 718b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * @return The tag object previously set by the application 719b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell * @see #setTag(Object) 720b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell */ 721b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell public Object getTag() { 722b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell return mTag; 723b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 724b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 7251357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 7261357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide (to be un-hidden) 7271357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @return the type of playback associated with this route 7281357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @see UserRouteInfo#setPlaybackType(int) 7291357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 7301357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public int getPlaybackType() { 7311357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi return mPlaybackType; 7321357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 7331357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 7341357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 7351357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide (to be un-hidden) 7361357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @return the stream over which the playback associated with this route is performed 7371357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @see UserRouteInfo#setPlaybackStream(int) 7381357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 7391357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public int getPlaybackStream() { 7401357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi return mPlaybackStream; 7411357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 7421357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 7431357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 7441357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide (to be un-hidden) 7451357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @return the volume at which the playback associated with this route is performed 7461357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @see UserRouteInfo#setVolume(int) 7471357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 7481357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public int getVolume() { 7491357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi if (mPlaybackType == PLAYBACK_TYPE_LOCAL) { 7501357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi int vol = 0; 7511357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi try { 7521357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi vol = sStatic.mAudioService.getStreamVolume(mPlaybackStream); 7531357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } catch (RemoteException e) { 7541357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi Log.e(TAG, "Error getting local stream volume", e); 7551357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 7561357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi return vol; 7571357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } else { 7581357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi return mVolume; 7591357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 7601357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 7611357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 7621357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 7631357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide (to be un-hidden) 7641357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @return the maximum volume at which the playback associated with this route is performed 7651357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @see UserRouteInfo#setVolumeMax(int) 7661357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 7671357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public int getVolumeMax() { 7681357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi if (mPlaybackType == PLAYBACK_TYPE_LOCAL) { 7691357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi int volMax = 0; 7701357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi try { 7711357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi volMax = sStatic.mAudioService.getStreamMaxVolume(mPlaybackStream); 7721357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } catch (RemoteException e) { 7731357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi Log.e(TAG, "Error getting local stream volume", e); 7741357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 7751357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi return volMax; 7761357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } else { 7771357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi return mVolumeMax; 7781357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 7791357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 7801357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 7811357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 7821357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide (to be un-hidden) 7831357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @return how volume is handling on the route 7841357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @see UserRouteInfo#setVolumeHandling(int) 7851357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 7861357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public int getVolumeHandling() { 7871357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi return mVolumeHandling; 7881357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 7891357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 7909a1de308cea2d160778fd977825f10a07b49d738Adam Powell void setStatusInt(CharSequence status) { 7919a1de308cea2d160778fd977825f10a07b49d738Adam Powell if (!status.equals(mStatus)) { 7929a1de308cea2d160778fd977825f10a07b49d738Adam Powell mStatus = status; 7939a1de308cea2d160778fd977825f10a07b49d738Adam Powell if (mGroup != null) { 7949a1de308cea2d160778fd977825f10a07b49d738Adam Powell mGroup.memberStatusChanged(this, status); 7959a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 7969a1de308cea2d160778fd977825f10a07b49d738Adam Powell routeUpdated(); 7979a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 7989a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 7999a1de308cea2d160778fd977825f10a07b49d738Adam Powell 8001357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi final IRemoteVolumeObserver.Stub mRemoteVolObserver = new IRemoteVolumeObserver.Stub() { 8011357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public void dispatchRemoteVolumeUpdate(final int direction, final int value) { 8021357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi sStatic.mHandler.post(new Runnable() { 8031357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi @Override 8041357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public void run() { 8051357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi //Log.d(TAG, "dispatchRemoteVolumeUpdate dir=" + direction + " val=" + value); 8061357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi if (mVcb != null) { 8071357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi if (direction != 0) { 8081357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi mVcb.vcb.onVolumeUpdateRequest(mVcb.route, direction); 8091357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } else { 8101357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi mVcb.vcb.onVolumeSetRequest(mVcb.route, value); 8111357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 8121357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 8131357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 8141357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi }); 8151357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 8161357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi }; 8171357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 8189a1de308cea2d160778fd977825f10a07b49d738Adam Powell void routeUpdated() { 8199a1de308cea2d160778fd977825f10a07b49d738Adam Powell updateRoute(this); 8209a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 8219a1de308cea2d160778fd977825f10a07b49d738Adam Powell 8229a1de308cea2d160778fd977825f10a07b49d738Adam Powell @Override 8239a1de308cea2d160778fd977825f10a07b49d738Adam Powell public String toString() { 824d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell String supportedTypes = typesToString(getSupportedTypes()); 825d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell return getClass().getSimpleName() + "{ name=" + getName() + ", status=" + getStatus() + 826d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell " category=" + getCategory() + 8279a1de308cea2d160778fd977825f10a07b49d738Adam Powell " supportedTypes=" + supportedTypes + "}"; 8289a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 8299a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 8309a1de308cea2d160778fd977825f10a07b49d738Adam Powell 8319a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 8329a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Information about a route that the application may define and modify. 8339a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 8349a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @see MediaRouter.RouteInfo 8359a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 836b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn public static class UserRouteInfo extends RouteInfo { 837ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell RemoteControlClient mRcc; 8389a1de308cea2d160778fd977825f10a07b49d738Adam Powell 8399a1de308cea2d160778fd977825f10a07b49d738Adam Powell UserRouteInfo(RouteCategory category) { 8409a1de308cea2d160778fd977825f10a07b49d738Adam Powell super(category); 8419a1de308cea2d160778fd977825f10a07b49d738Adam Powell mSupportedTypes = ROUTE_TYPE_USER; 8429a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 8439a1de308cea2d160778fd977825f10a07b49d738Adam Powell 8449a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 8459a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Set the user-visible name of this route. 8469a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param name Name to display to the user to describe this route 8479a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 8489a1de308cea2d160778fd977825f10a07b49d738Adam Powell public void setName(CharSequence name) { 8499a1de308cea2d160778fd977825f10a07b49d738Adam Powell mName = name; 8509a1de308cea2d160778fd977825f10a07b49d738Adam Powell routeUpdated(); 8519a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 8520d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell 8530d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell /** 8540d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * Set the user-visible name of this route. 8550d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * @param resId Resource ID of the name to display to the user to describe this route 8560d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell */ 8570d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell public void setName(int resId) { 8580d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell mNameResId = resId; 8590d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell mName = null; 8600d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell routeUpdated(); 8610d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell } 8629a1de308cea2d160778fd977825f10a07b49d738Adam Powell 8639a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 8649a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Set the current user-visible status for this route. 8659a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param status Status to display to the user to describe what the endpoint 8669a1de308cea2d160778fd977825f10a07b49d738Adam Powell * of this route is currently doing 8679a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 8689a1de308cea2d160778fd977825f10a07b49d738Adam Powell public void setStatus(CharSequence status) { 8699a1de308cea2d160778fd977825f10a07b49d738Adam Powell setStatusInt(status); 8709a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 871ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell 872ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell /** 873ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * Set the RemoteControlClient responsible for reporting playback info for this 874ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * user route. 875ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * 876ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * <p>If this route manages remote playback, the data exposed by this 877ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * RemoteControlClient will be used to reflect and update information 878ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * such as route volume info in related UIs.</p> 879ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * 8801357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * <p>The RemoteControlClient must have been previously registered with 8811357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * {@link AudioManager#registerRemoteControlClient(RemoteControlClient)}.</p> 8821357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * 883ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * @param rcc RemoteControlClient associated with this route 884ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell */ 885ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell public void setRemoteControlClient(RemoteControlClient rcc) { 886ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell mRcc = rcc; 8871357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi updatePlaybackInfoOnRcc(); 888ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell } 889ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell 890ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell /** 8914599696591f745b3a546197d2ba7e5cfc5562484Adam Powell * Retrieve the RemoteControlClient associated with this route, if one has been set. 8924599696591f745b3a546197d2ba7e5cfc5562484Adam Powell * 8934599696591f745b3a546197d2ba7e5cfc5562484Adam Powell * @return the RemoteControlClient associated with this route 8944599696591f745b3a546197d2ba7e5cfc5562484Adam Powell * @see #setRemoteControlClient(RemoteControlClient) 8954599696591f745b3a546197d2ba7e5cfc5562484Adam Powell */ 8964599696591f745b3a546197d2ba7e5cfc5562484Adam Powell public RemoteControlClient getRemoteControlClient() { 8974599696591f745b3a546197d2ba7e5cfc5562484Adam Powell return mRcc; 8984599696591f745b3a546197d2ba7e5cfc5562484Adam Powell } 8994599696591f745b3a546197d2ba7e5cfc5562484Adam Powell 9004599696591f745b3a546197d2ba7e5cfc5562484Adam Powell /** 901ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * Set an icon that will be used to represent this route. 902ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * The system may use this icon in picker UIs or similar. 903ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * 904ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * @param icon icon drawable to use to represent this route 905ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell */ 906ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell public void setIconDrawable(Drawable icon) { 907ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell mIcon = icon; 908ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell } 909ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell 910ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell /** 911ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * Set an icon that will be used to represent this route. 912ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * The system may use this icon in picker UIs or similar. 913ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * 91471c69897ad0a55d590698bfa399bfe99c763b9dbAdam Powell * @param resId Resource ID of an icon drawable to use to represent this route 915ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell */ 916ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell public void setIconResource(int resId) { 917ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell setIconDrawable(sStatic.mResources.getDrawable(resId)); 918ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell } 9191357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 9201357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 9211357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide (to be un-hidden) 9221357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * Set a callback to be notified of volume update requests 9231357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @param vcb 9241357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 9251357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public void setVolumeCallback(VolumeCallback vcb) { 9261357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi mVcb = new VolumeCallbackInfo(vcb, this); 9271357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 9281357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 9291357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 9301357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide (to be un-hidden) 9311357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * Defines whether playback associated with this route is "local" 9321357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * ({@link RouteInfo#PLAYBACK_TYPE_LOCAL}) or "remote" 9331357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * ({@link RouteInfo#PLAYBACK_TYPE_REMOTE}). 9341357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @param type 9351357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 9361357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public void setPlaybackType(int type) { 9371357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi if (mPlaybackType != type) { 9381357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi mPlaybackType = type; 9391357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi setPlaybackInfoOnRcc(RemoteControlClient.PLAYBACKINFO_PLAYBACK_TYPE, type); 9401357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 9411357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 9421357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 9431357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 9441357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide (to be un-hidden) 9451357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * Defines whether volume for the playback associated with this route is fixed 9461357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * ({@link RouteInfo#PLAYBACK_VOLUME_FIXED}) or can modified 9471357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * ({@link RouteInfo#PLAYBACK_VOLUME_VARIABLE}). 9481357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @param volumeHandling 9491357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 9501357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public void setVolumeHandling(int volumeHandling) { 9511357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi if (mVolumeHandling != volumeHandling) { 9521357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi mVolumeHandling = volumeHandling; 9531357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi setPlaybackInfoOnRcc( 9541357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi RemoteControlClient.PLAYBACKINFO_VOLUME_HANDLING, volumeHandling); 9551357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 9561357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 9571357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 9581357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 9591357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide (to be un-hidden) 9601357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * Defines at what volume the playback associated with this route is performed (for user 9611357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * feedback purposes). This information is only used when the playback is not local. 9621357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @param volume 9631357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 9641357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public void setVolume(int volume) { 9651357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi if (mVolume != volume) { 9661357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi mVolume = volume; 9671357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi setPlaybackInfoOnRcc(RemoteControlClient.PLAYBACKINFO_VOLUME, volume); 9681357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 9691357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 9701357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 9711357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 9721357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide (to be un-hidden) 9731357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * Defines the maximum volume at which the playback associated with this route is performed 9741357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * (for user feedback purposes). This information is only used when the playback is not 9751357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * local. 9761357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @param volumeMax 9771357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 9781357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public void setVolumeMax(int volumeMax) { 9791357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi if (mVolumeMax != volumeMax) { 9801357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi mVolumeMax = volumeMax; 9811357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi setPlaybackInfoOnRcc(RemoteControlClient.PLAYBACKINFO_VOLUME_MAX, volumeMax); 9821357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 9831357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 9841357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 9851357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 9861357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide (to be un-hidden) 9871357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * Defines over what stream type the media is presented. 9881357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @param stream 9891357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 9901357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public void setPlaybackStream(int stream) { 9911357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi if (mPlaybackStream != stream) { 9921357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi mPlaybackStream = stream; 9931357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi setPlaybackInfoOnRcc(RemoteControlClient.PLAYBACKINFO_USES_STREAM, stream); 9941357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 9951357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 9961357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 9971357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi private void updatePlaybackInfoOnRcc() { 9981357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi if ((mRcc != null) && (mRcc.getRcseId() != RemoteControlClient.RCSE_ID_UNREGISTERED)) { 9991357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi mRcc.setPlaybackInformation( 10001357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi RemoteControlClient.PLAYBACKINFO_VOLUME_MAX, mVolumeMax); 10011357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi mRcc.setPlaybackInformation( 10021357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi RemoteControlClient.PLAYBACKINFO_VOLUME, mVolume); 10031357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi mRcc.setPlaybackInformation( 10041357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi RemoteControlClient.PLAYBACKINFO_VOLUME_HANDLING, mVolumeHandling); 10051357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi mRcc.setPlaybackInformation( 10061357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi RemoteControlClient.PLAYBACKINFO_USES_STREAM, mPlaybackStream); 10071357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi mRcc.setPlaybackInformation( 10081357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi RemoteControlClient.PLAYBACKINFO_PLAYBACK_TYPE, mPlaybackType); 10091357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi // let AudioService know whom to call when remote volume needs to be updated 10101357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi try { 10111357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi sStatic.mAudioService.registerRemoteVolumeObserverForRcc( 10121357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi mRcc.getRcseId() /* rccId */, mRemoteVolObserver /* rvo */); 10131357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } catch (RemoteException e) { 10141357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi Log.e(TAG, "Error registering remote volume observer", e); 10151357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 10161357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 10171357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 10181357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 10191357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi private void setPlaybackInfoOnRcc(int what, int value) { 10201357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi if (mRcc != null) { 10211357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi mRcc.setPlaybackInformation(what, value); 10221357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 10231357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 10249a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 10259a1de308cea2d160778fd977825f10a07b49d738Adam Powell 10269a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 10279a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Information about a route that consists of multiple other routes in a group. 10289a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 1029b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn public static class RouteGroup extends RouteInfo { 10309a1de308cea2d160778fd977825f10a07b49d738Adam Powell final ArrayList<RouteInfo> mRoutes = new ArrayList<RouteInfo>(); 10319a1de308cea2d160778fd977825f10a07b49d738Adam Powell private boolean mUpdateName; 10329a1de308cea2d160778fd977825f10a07b49d738Adam Powell 10339a1de308cea2d160778fd977825f10a07b49d738Adam Powell RouteGroup(RouteCategory category) { 10349a1de308cea2d160778fd977825f10a07b49d738Adam Powell super(category); 10359a1de308cea2d160778fd977825f10a07b49d738Adam Powell mGroup = this; 10369a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 10379a1de308cea2d160778fd977825f10a07b49d738Adam Powell 10380d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell CharSequence getName(Resources res) { 10399a1de308cea2d160778fd977825f10a07b49d738Adam Powell if (mUpdateName) updateName(); 10400d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell return super.getName(res); 10419a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 10429a1de308cea2d160778fd977825f10a07b49d738Adam Powell 10439a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 10449a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Add a route to this group. The route must not currently belong to another group. 10459a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 10469a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param route route to add to this group 10479a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 10489a1de308cea2d160778fd977825f10a07b49d738Adam Powell public void addRoute(RouteInfo route) { 10499a1de308cea2d160778fd977825f10a07b49d738Adam Powell if (route.getGroup() != null) { 10509a1de308cea2d160778fd977825f10a07b49d738Adam Powell throw new IllegalStateException("Route " + route + " is already part of a group."); 10519a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 10529a1de308cea2d160778fd977825f10a07b49d738Adam Powell if (route.getCategory() != mCategory) { 10539a1de308cea2d160778fd977825f10a07b49d738Adam Powell throw new IllegalArgumentException( 10549a1de308cea2d160778fd977825f10a07b49d738Adam Powell "Route cannot be added to a group with a different category. " + 10559a1de308cea2d160778fd977825f10a07b49d738Adam Powell "(Route category=" + route.getCategory() + 10569a1de308cea2d160778fd977825f10a07b49d738Adam Powell " group category=" + mCategory + ")"); 10579a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 1058d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell final int at = mRoutes.size(); 10599a1de308cea2d160778fd977825f10a07b49d738Adam Powell mRoutes.add(route); 1060d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell route.mGroup = this; 10619a1de308cea2d160778fd977825f10a07b49d738Adam Powell mUpdateName = true; 1062d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell dispatchRouteGrouped(route, this, at); 10639a1de308cea2d160778fd977825f10a07b49d738Adam Powell routeUpdated(); 10649a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 10659a1de308cea2d160778fd977825f10a07b49d738Adam Powell 10669a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 10679a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Add a route to this group before the specified index. 10689a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 10699a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param route route to add 10709a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param insertAt insert the new route before this index 10719a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 10729a1de308cea2d160778fd977825f10a07b49d738Adam Powell public void addRoute(RouteInfo route, int insertAt) { 10739a1de308cea2d160778fd977825f10a07b49d738Adam Powell if (route.getGroup() != null) { 10749a1de308cea2d160778fd977825f10a07b49d738Adam Powell throw new IllegalStateException("Route " + route + " is already part of a group."); 10759a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 10769a1de308cea2d160778fd977825f10a07b49d738Adam Powell if (route.getCategory() != mCategory) { 10779a1de308cea2d160778fd977825f10a07b49d738Adam Powell throw new IllegalArgumentException( 10789a1de308cea2d160778fd977825f10a07b49d738Adam Powell "Route cannot be added to a group with a different category. " + 10799a1de308cea2d160778fd977825f10a07b49d738Adam Powell "(Route category=" + route.getCategory() + 10809a1de308cea2d160778fd977825f10a07b49d738Adam Powell " group category=" + mCategory + ")"); 10819a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 10829a1de308cea2d160778fd977825f10a07b49d738Adam Powell mRoutes.add(insertAt, route); 1083d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell route.mGroup = this; 10849a1de308cea2d160778fd977825f10a07b49d738Adam Powell mUpdateName = true; 1085d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell dispatchRouteGrouped(route, this, insertAt); 10869a1de308cea2d160778fd977825f10a07b49d738Adam Powell routeUpdated(); 10879a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 10889a1de308cea2d160778fd977825f10a07b49d738Adam Powell 10899a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 10909a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Remove a route from this group. 10919a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 10929a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param route route to remove 10939a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 10949a1de308cea2d160778fd977825f10a07b49d738Adam Powell public void removeRoute(RouteInfo route) { 10959a1de308cea2d160778fd977825f10a07b49d738Adam Powell if (route.getGroup() != this) { 10969a1de308cea2d160778fd977825f10a07b49d738Adam Powell throw new IllegalArgumentException("Route " + route + 10979a1de308cea2d160778fd977825f10a07b49d738Adam Powell " is not a member of this group."); 10989a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 10999a1de308cea2d160778fd977825f10a07b49d738Adam Powell mRoutes.remove(route); 1100d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell route.mGroup = null; 11019a1de308cea2d160778fd977825f10a07b49d738Adam Powell mUpdateName = true; 1102d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell dispatchRouteUngrouped(route, this); 11039a1de308cea2d160778fd977825f10a07b49d738Adam Powell routeUpdated(); 11049a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 11059a1de308cea2d160778fd977825f10a07b49d738Adam Powell 11069a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 11079a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Remove the route at the specified index from this group. 11089a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 11099a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param index index of the route to remove 11109a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 11119a1de308cea2d160778fd977825f10a07b49d738Adam Powell public void removeRoute(int index) { 1112d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell RouteInfo route = mRoutes.remove(index); 1113d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell route.mGroup = null; 11149a1de308cea2d160778fd977825f10a07b49d738Adam Powell mUpdateName = true; 1115d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell dispatchRouteUngrouped(route, this); 11169a1de308cea2d160778fd977825f10a07b49d738Adam Powell routeUpdated(); 11179a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 11189a1de308cea2d160778fd977825f10a07b49d738Adam Powell 1119d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell /** 1120d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @return The number of routes in this group 1121d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell */ 1122d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell public int getRouteCount() { 1123d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell return mRoutes.size(); 1124d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell } 1125d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell 1126d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell /** 1127d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * Return the route in this group at the specified index 1128d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * 1129d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @param index Index to fetch 1130d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @return The route at index 1131d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell */ 1132d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell public RouteInfo getRouteAt(int index) { 1133d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell return mRoutes.get(index); 1134d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell } 1135d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell 1136ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell /** 1137ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * Set an icon that will be used to represent this group. 1138ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * The system may use this icon in picker UIs or similar. 1139ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * 1140ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * @param icon icon drawable to use to represent this group 1141ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell */ 1142ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell public void setIconDrawable(Drawable icon) { 1143ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell mIcon = icon; 1144ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell } 1145ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell 1146ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell /** 1147ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * Set an icon that will be used to represent this group. 1148ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * The system may use this icon in picker UIs or similar. 1149ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell * 115071c69897ad0a55d590698bfa399bfe99c763b9dbAdam Powell * @param resId Resource ID of an icon drawable to use to represent this group 1151ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell */ 1152ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell public void setIconResource(int resId) { 1153ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell setIconDrawable(sStatic.mResources.getDrawable(resId)); 1154ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell } 1155ae20ae1a8aaa013813c356ae1d9541ca7ff020aeAdam Powell 11569a1de308cea2d160778fd977825f10a07b49d738Adam Powell void memberNameChanged(RouteInfo info, CharSequence name) { 11579a1de308cea2d160778fd977825f10a07b49d738Adam Powell mUpdateName = true; 11589a1de308cea2d160778fd977825f10a07b49d738Adam Powell routeUpdated(); 11599a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 11609a1de308cea2d160778fd977825f10a07b49d738Adam Powell 11619a1de308cea2d160778fd977825f10a07b49d738Adam Powell void memberStatusChanged(RouteInfo info, CharSequence status) { 11629a1de308cea2d160778fd977825f10a07b49d738Adam Powell setStatusInt(status); 11639a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 11649a1de308cea2d160778fd977825f10a07b49d738Adam Powell 1165d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell @Override 1166d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell void routeUpdated() { 1167d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell int types = 0; 1168d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell final int count = mRoutes.size(); 1169b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell if (count == 0) { 1170b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell // Don't keep empty groups in the router. 1171b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell MediaRouter.removeRoute(this); 1172b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell return; 1173b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell } 1174b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell 1175d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell for (int i = 0; i < count; i++) { 1176d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell types |= mRoutes.get(i).mSupportedTypes; 1177d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 1178d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell mSupportedTypes = types; 1179d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell mIcon = count == 1 ? mRoutes.get(0).getIconDrawable() : null; 1180d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell super.routeUpdated(); 1181d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 1182d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell 11839a1de308cea2d160778fd977825f10a07b49d738Adam Powell void updateName() { 11849a1de308cea2d160778fd977825f10a07b49d738Adam Powell final StringBuilder sb = new StringBuilder(); 11859a1de308cea2d160778fd977825f10a07b49d738Adam Powell final int count = mRoutes.size(); 11869a1de308cea2d160778fd977825f10a07b49d738Adam Powell for (int i = 0; i < count; i++) { 11879a1de308cea2d160778fd977825f10a07b49d738Adam Powell final RouteInfo info = mRoutes.get(i); 1188b5e2af5919351486a385effe77409d2a91ae9c19Adam Powell // TODO: There's probably a much more correct way to localize this. 11899a1de308cea2d160778fd977825f10a07b49d738Adam Powell if (i > 0) sb.append(", "); 11909a1de308cea2d160778fd977825f10a07b49d738Adam Powell sb.append(info.mName); 11919a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 11929a1de308cea2d160778fd977825f10a07b49d738Adam Powell mName = sb.toString(); 11939a1de308cea2d160778fd977825f10a07b49d738Adam Powell mUpdateName = false; 11949a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 1195d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell 1196d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell @Override 1197d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell public String toString() { 1198d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell StringBuilder sb = new StringBuilder(super.toString()); 1199d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell sb.append('['); 1200d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell final int count = mRoutes.size(); 1201d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell for (int i = 0; i < count; i++) { 1202d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell if (i > 0) sb.append(", "); 1203d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell sb.append(mRoutes.get(i)); 1204d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 1205d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell sb.append(']'); 1206d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell return sb.toString(); 1207d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell } 12089a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 12099a1de308cea2d160778fd977825f10a07b49d738Adam Powell 12109a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 12119a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Definition of a category of routes. All routes belong to a category. 12129a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 1213b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn public static class RouteCategory { 12149a1de308cea2d160778fd977825f10a07b49d738Adam Powell CharSequence mName; 12150d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell int mNameResId; 12169a1de308cea2d160778fd977825f10a07b49d738Adam Powell int mTypes; 12179a1de308cea2d160778fd977825f10a07b49d738Adam Powell final boolean mGroupable; 12189a1de308cea2d160778fd977825f10a07b49d738Adam Powell 12199a1de308cea2d160778fd977825f10a07b49d738Adam Powell RouteCategory(CharSequence name, int types, boolean groupable) { 12209a1de308cea2d160778fd977825f10a07b49d738Adam Powell mName = name; 12219a1de308cea2d160778fd977825f10a07b49d738Adam Powell mTypes = types; 12229a1de308cea2d160778fd977825f10a07b49d738Adam Powell mGroupable = groupable; 12239a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 12249a1de308cea2d160778fd977825f10a07b49d738Adam Powell 12250d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell RouteCategory(int nameResId, int types, boolean groupable) { 12260d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell mNameResId = nameResId; 12270d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell mTypes = types; 12280d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell mGroupable = groupable; 12290d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell } 12300d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell 12319a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 12329a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @return the name of this route category 12339a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 12349a1de308cea2d160778fd977825f10a07b49d738Adam Powell public CharSequence getName() { 12350d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell return getName(sStatic.mResources); 12360d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell } 12370d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell 12380d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell /** 12390d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * Return the properly localized/configuration dependent name of this RouteCategory. 12400d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * 12410d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * @param context Context to resolve name resources 12420d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * @return the name of this route category 12430d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell */ 12440d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell public CharSequence getName(Context context) { 12450d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell return getName(context.getResources()); 12460d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell } 12470d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell 12480d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell CharSequence getName(Resources res) { 12490d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell if (mNameResId != 0) { 12500d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell return res.getText(mNameResId); 12510d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell } 12529a1de308cea2d160778fd977825f10a07b49d738Adam Powell return mName; 12539a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 12549a1de308cea2d160778fd977825f10a07b49d738Adam Powell 12559a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 1256d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * Return the current list of routes in this category that have been added 1257d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * to the MediaRouter. 12589a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 1259d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * <p>This list will not include routes that are nested within RouteGroups. 1260d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * A RouteGroup is treated as a single route within its category.</p> 1261d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * 1262d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @param out a List to fill with the routes in this category. If this parameter is 1263d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * non-null, it will be cleared, filled with the current routes with this 1264d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * category, and returned. If this parameter is null, a new List will be 1265d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * allocated to report the category's current routes. 1266d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @return A list with the routes in this category that have been added to the MediaRouter. 12679a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 1268d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell public List<RouteInfo> getRoutes(List<RouteInfo> out) { 1269d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell if (out == null) { 1270d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell out = new ArrayList<RouteInfo>(); 1271d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell } else { 1272d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell out.clear(); 1273d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell } 1274d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell 1275b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn final int count = getRouteCountStatic(); 1276d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell for (int i = 0; i < count; i++) { 1277b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn final RouteInfo route = getRouteAtStatic(i); 1278d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell if (route.mCategory == this) { 1279d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell out.add(route); 1280d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell } 1281d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell } 1282d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell return out; 12839a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 12849a1de308cea2d160778fd977825f10a07b49d738Adam Powell 12859a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 12869a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @return Flag set describing the route types supported by this category 12879a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 12889a1de308cea2d160778fd977825f10a07b49d738Adam Powell public int getSupportedTypes() { 12899a1de308cea2d160778fd977825f10a07b49d738Adam Powell return mTypes; 12909a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 12919a1de308cea2d160778fd977825f10a07b49d738Adam Powell 12929a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 12939a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Return whether or not this category supports grouping. 12949a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 12959a1de308cea2d160778fd977825f10a07b49d738Adam Powell * <p>If this method returns true, all routes obtained from this category 1296d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * via calls to {@link #getRouteAt(int)} will be {@link MediaRouter.RouteGroup}s.</p> 12979a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 12989a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @return true if this category supports 12999a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 13009a1de308cea2d160778fd977825f10a07b49d738Adam Powell public boolean isGroupable() { 13019a1de308cea2d160778fd977825f10a07b49d738Adam Powell return mGroupable; 13029a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 13039a1de308cea2d160778fd977825f10a07b49d738Adam Powell 13049a1de308cea2d160778fd977825f10a07b49d738Adam Powell public String toString() { 13059a1de308cea2d160778fd977825f10a07b49d738Adam Powell return "RouteCategory{ name=" + mName + " types=" + typesToString(mTypes) + 1306d6d0bddee363e0c7fe61f63bd9d9864a71d887d6Adam Powell " groupable=" + mGroupable + " }"; 13079a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 13089a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 13099a1de308cea2d160778fd977825f10a07b49d738Adam Powell 13109a1de308cea2d160778fd977825f10a07b49d738Adam Powell static class CallbackInfo { 13119a1de308cea2d160778fd977825f10a07b49d738Adam Powell public int type; 1312b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn public final Callback cb; 1313b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn public final MediaRouter router; 13149a1de308cea2d160778fd977825f10a07b49d738Adam Powell 1315b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn public CallbackInfo(Callback cb, int type, MediaRouter router) { 13169a1de308cea2d160778fd977825f10a07b49d738Adam Powell this.cb = cb; 13179a1de308cea2d160778fd977825f10a07b49d738Adam Powell this.type = type; 1318b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn this.router = router; 13199a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 13209a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 13219a1de308cea2d160778fd977825f10a07b49d738Adam Powell 13229a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 13239a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Interface for receiving events about media routing changes. 13249a1de308cea2d160778fd977825f10a07b49d738Adam Powell * All methods of this interface will be called from the application's main thread. 13259a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 13269a1de308cea2d160778fd977825f10a07b49d738Adam Powell * <p>A Callback will only receive events relevant to routes that the callback 13279a1de308cea2d160778fd977825f10a07b49d738Adam Powell * was registered for.</p> 13289a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 13299a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @see MediaRouter#addCallback(int, Callback) 13309a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @see MediaRouter#removeCallback(Callback) 13319a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 13320d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell public static abstract class Callback { 13339a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 13349a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Called when the supplied route becomes selected as the active route 13359a1de308cea2d160778fd977825f10a07b49d738Adam Powell * for the given route type. 13369a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 1337d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @param router the MediaRouter reporting the event 13389a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param type Type flag set indicating the routes that have been selected 13399a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param info Route that has been selected for the given route types 13409a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 13410d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell public abstract void onRouteSelected(MediaRouter router, int type, RouteInfo info); 13429a1de308cea2d160778fd977825f10a07b49d738Adam Powell 13439a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 13449a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Called when the supplied route becomes unselected as the active route 13459a1de308cea2d160778fd977825f10a07b49d738Adam Powell * for the given route type. 13469a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 1347d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @param router the MediaRouter reporting the event 13489a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param type Type flag set indicating the routes that have been unselected 13499a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param info Route that has been unselected for the given route types 13509a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 13510d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell public abstract void onRouteUnselected(MediaRouter router, int type, RouteInfo info); 13529a1de308cea2d160778fd977825f10a07b49d738Adam Powell 13539a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 13549a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Called when a route for the specified type was added. 13559a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 1356d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @param router the MediaRouter reporting the event 13579a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param info Route that has become available for use 13589a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 13590d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell public abstract void onRouteAdded(MediaRouter router, RouteInfo info); 13609a1de308cea2d160778fd977825f10a07b49d738Adam Powell 13619a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 13629a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Called when a route for the specified type was removed. 13639a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 1364d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @param router the MediaRouter reporting the event 13659a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param info Route that has been removed from availability 13669a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 13670d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell public abstract void onRouteRemoved(MediaRouter router, RouteInfo info); 13689a1de308cea2d160778fd977825f10a07b49d738Adam Powell 13699a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 13709a1de308cea2d160778fd977825f10a07b49d738Adam Powell * Called when an aspect of the indicated route has changed. 13719a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 13729a1de308cea2d160778fd977825f10a07b49d738Adam Powell * <p>This will not indicate that the types supported by this route have 13739a1de308cea2d160778fd977825f10a07b49d738Adam Powell * changed, only that cosmetic info such as name or status have been updated.</p> 13749a1de308cea2d160778fd977825f10a07b49d738Adam Powell * 1375d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @param router the MediaRouter reporting the event 13769a1de308cea2d160778fd977825f10a07b49d738Adam Powell * @param info The route that was changed 13779a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 13780d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell public abstract void onRouteChanged(MediaRouter router, RouteInfo info); 1379d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell 1380d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell /** 1381d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * Called when a route is added to a group. 1382d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * 1383d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @param router the MediaRouter reporting the event 1384d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @param info The route that was added 1385d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @param group The group the route was added to 1386d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @param index The route index within group that info was added at 1387d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell */ 13880d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell public abstract void onRouteGrouped(MediaRouter router, RouteInfo info, RouteGroup group, 13890d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell int index); 1390d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell 1391d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell /** 1392d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * Called when a route is removed from a group. 1393d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * 1394d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @param router the MediaRouter reporting the event 1395d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @param info The route that was removed 1396d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell * @param group The group the route was removed from 1397d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell */ 13980d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell public abstract void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group); 13999a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 14009a1de308cea2d160778fd977825f10a07b49d738Adam Powell 14019a1de308cea2d160778fd977825f10a07b49d738Adam Powell /** 14020d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * Stub implementation of {@link MediaRouter.Callback}. 14030d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell * Each abstract method is defined as a no-op. Override just the ones 14049a1de308cea2d160778fd977825f10a07b49d738Adam Powell * you need. 14059a1de308cea2d160778fd977825f10a07b49d738Adam Powell */ 14060d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell public static class SimpleCallback extends Callback { 14079a1de308cea2d160778fd977825f10a07b49d738Adam Powell 14089a1de308cea2d160778fd977825f10a07b49d738Adam Powell @Override 1409d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell public void onRouteSelected(MediaRouter router, int type, RouteInfo info) { 14109a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 14119a1de308cea2d160778fd977825f10a07b49d738Adam Powell 14129a1de308cea2d160778fd977825f10a07b49d738Adam Powell @Override 1413d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) { 14149a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 14159a1de308cea2d160778fd977825f10a07b49d738Adam Powell 14169a1de308cea2d160778fd977825f10a07b49d738Adam Powell @Override 1417d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell public void onRouteAdded(MediaRouter router, RouteInfo info) { 14189a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 14199a1de308cea2d160778fd977825f10a07b49d738Adam Powell 14209a1de308cea2d160778fd977825f10a07b49d738Adam Powell @Override 1421d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell public void onRouteRemoved(MediaRouter router, RouteInfo info) { 14229a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 14239a1de308cea2d160778fd977825f10a07b49d738Adam Powell 14249a1de308cea2d160778fd977825f10a07b49d738Adam Powell @Override 1425d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell public void onRouteChanged(MediaRouter router, RouteInfo info) { 14269a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 14279a1de308cea2d160778fd977825f10a07b49d738Adam Powell 14289a1de308cea2d160778fd977825f10a07b49d738Adam Powell @Override 1429d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell public void onRouteGrouped(MediaRouter router, RouteInfo info, RouteGroup group, 1430d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell int index) { 14319a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 14329a1de308cea2d160778fd977825f10a07b49d738Adam Powell 14339a1de308cea2d160778fd977825f10a07b49d738Adam Powell @Override 1434d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group) { 14359a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 1436d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell 14379a1de308cea2d160778fd977825f10a07b49d738Adam Powell } 14381357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 14391357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi static class VolumeCallbackInfo { 14401357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public final VolumeCallback vcb; 14411357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public final RouteInfo route; 14421357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 14431357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public VolumeCallbackInfo(VolumeCallback vcb, RouteInfo route) { 14441357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi this.vcb = vcb; 14451357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi this.route = route; 14461357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 14471357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 14481357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 14491357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 14501357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @hide (to be un-hidden) 14511357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * Interface for receiving events about volume changes. 14521357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * All methods of this interface will be called from the application's main thread. 14531357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * 14541357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * <p>A VolumeCallback will only receive events relevant to routes that the callback 14551357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * was registered for.</p> 14561357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * 14571357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @see UserRouteInfo#setVolumeCallback(VolumeCallback) 14581357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 14591357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public static abstract class VolumeCallback { 14601357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 14611357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * Called when the volume for the route should be increased or decreased. 14621357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @param info the route affected by this event 14631357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @param direction an integer indicating whether the volume is to be increased 14641357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * (positive value) or decreased (negative value). 14651357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * For bundled changes, the absolute value indicates the number of changes 14661357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * in the same direction, e.g. +3 corresponds to three "volume up" changes. 14671357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 14681357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public abstract void onVolumeUpdateRequest(RouteInfo info, int direction); 14691357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi /** 14701357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * Called when the volume for the route should be set to the given value 14711357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @param info the route affected by this event 14721357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * @param volume an integer indicating the new volume value that should be used, always 14731357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi * between 0 and the value set by {@link UserRouteInfo#setVolumeMax(int)}. 14741357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi */ 14751357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi public abstract void onVolumeSetRequest(RouteInfo info, int volume); 14761357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi } 14771357012968f9066ea3051d83995e9bac69526c3cJean-Michel Trivi 14789a1de308cea2d160778fd977825f10a07b49d738Adam Powell} 1479