MediaRouteButton.java revision de0d5d746fc030770b64858b64eac2b1c26e4ba6
1690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell/* 2690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * Copyright (C) 2012 The Android Open Source Project 3690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * 4690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * Licensed under the Apache License, Version 2.0 (the "License"); 5690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * you may not use this file except in compliance with the License. 6690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * You may obtain a copy of the License at 7690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * 8690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * http://www.apache.org/licenses/LICENSE-2.0 9690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * 10690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * Unless required by applicable law or agreed to in writing, software 11690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * distributed under the License is distributed on an "AS IS" BASIS, 12690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * See the License for the specific language governing permissions and 14690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * limitations under the License. 15690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell */ 16690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 17690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellpackage android.app; 18690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 19690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport com.android.internal.R; 200abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport com.android.internal.app.MediaRouteDialogPresenter; 21690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 22690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.content.Context; 2370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.content.ContextWrapper; 24690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.content.res.TypedArray; 25690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.graphics.Canvas; 26e4681878702edaf0833294b3f1ce835705d3ad04Adam Powellimport android.graphics.Rect; 27690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.graphics.drawable.Drawable; 28690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.media.MediaRouter; 29f7e0a328c939fa61792d4b685e8f9047a3a0ad90Adam Powellimport android.media.MediaRouter.RouteGroup; 30690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.media.MediaRouter.RouteInfo; 31e4681878702edaf0833294b3f1ce835705d3ad04Adam Powellimport android.text.TextUtils; 32690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.util.AttributeSet; 33e4681878702edaf0833294b3f1ce835705d3ad04Adam Powellimport android.view.Gravity; 34e4681878702edaf0833294b3f1ce835705d3ad04Adam Powellimport android.view.HapticFeedbackConstants; 35690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.view.SoundEffectConstants; 36690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.view.View; 37e4681878702edaf0833294b3f1ce835705d3ad04Adam Powellimport android.widget.Toast; 38690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 39690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellpublic class MediaRouteButton extends View { 400abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown private final MediaRouter mRouter; 410abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown private final MediaRouterCallback mCallback; 42690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 43690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private int mRouteTypes; 44690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 45101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich private boolean mAttachedToWindow; 46101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich 47690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private Drawable mRemoteIndicator; 48690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private boolean mRemoteActive; 49e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell private boolean mCheatSheetEnabled; 502ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell private boolean mIsConnecting; 51690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 52690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private int mMinWidth; 53690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private int mMinHeight; 54690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 55b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell private OnClickListener mExtendedSettingsClickListener; 56b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell 570abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown // The checked state is used when connected to a remote route. 582ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell private static final int[] CHECKED_STATE_SET = { 592ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell R.attr.state_checked 602ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell }; 612ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell 620abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown // The activated state is used while connecting to a remote route. 63690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private static final int[] ACTIVATED_STATE_SET = { 64690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell R.attr.state_activated 65690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell }; 66690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 67690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public MediaRouteButton(Context context) { 68690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell this(context, null); 69690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 70690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 71690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public MediaRouteButton(Context context, AttributeSet attrs) { 7274d762a3ee7dd66fe9ce44f3232159811af8d5d8Adam Powell this(context, attrs, com.android.internal.R.attr.mediaRouteButtonStyle); 73690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 74690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 75690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public MediaRouteButton(Context context, AttributeSet attrs, int defStyleAttr) { 76617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette this(context, attrs, defStyleAttr, 0); 77617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette } 78617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette 79617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette public MediaRouteButton( 80617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 81617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette super(context, attrs, defStyleAttr, defStyleRes); 82690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 83b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn mRouter = (MediaRouter)context.getSystemService(Context.MEDIA_ROUTER_SERVICE); 840abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown mCallback = new MediaRouterCallback(); 85690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 86617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette final TypedArray a = context.obtainStyledAttributes(attrs, 87617feb99a06e7ffb3894e86a286bf30e085f321aAlan Viverette com.android.internal.R.styleable.MediaRouteButton, defStyleAttr, defStyleRes); 88690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell setRemoteIndicatorDrawable(a.getDrawable( 89690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell com.android.internal.R.styleable.MediaRouteButton_externalRouteEnabledDrawable)); 90690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mMinWidth = a.getDimensionPixelSize( 91690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell com.android.internal.R.styleable.MediaRouteButton_minWidth, 0); 92690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mMinHeight = a.getDimensionPixelSize( 93690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell com.android.internal.R.styleable.MediaRouteButton_minHeight, 0); 94849df0b5a7a5ef72610d687a8b1c2f0a23f873abAdam Powell final int routeTypes = a.getInteger( 95849df0b5a7a5ef72610d687a8b1c2f0a23f873abAdam Powell com.android.internal.R.styleable.MediaRouteButton_mediaRouteTypes, 96849df0b5a7a5ef72610d687a8b1c2f0a23f873abAdam Powell MediaRouter.ROUTE_TYPE_LIVE_AUDIO); 97690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell a.recycle(); 98690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 99690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell setClickable(true); 100e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell setLongClickable(true); 101849df0b5a7a5ef72610d687a8b1c2f0a23f873abAdam Powell 102849df0b5a7a5ef72610d687a8b1c2f0a23f873abAdam Powell setRouteTypes(routeTypes); 103690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 104690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 1050abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown /** 1060abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * Gets the media route types for filtering the routes that the user can 1070abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * select using the media route chooser dialog. 1080abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * 1090abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * @return The route types. 1100abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown */ 1110abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown public int getRouteTypes() { 1120abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown return mRouteTypes; 1130abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown } 1140abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown 1150abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown /** 1160abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * Sets the types of routes that will be shown in the media route chooser dialog 1170abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * launched by this button. 1180abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * 1190abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * @param types The route types to match. 1200abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown */ 1210abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown public void setRouteTypes(int types) { 1220abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown if (mRouteTypes != types) { 1230abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown if (mAttachedToWindow && mRouteTypes != 0) { 1240abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown mRouter.removeCallback(mCallback); 1250abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown } 1260abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown 1270abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown mRouteTypes = types; 1280abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown 1290abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown if (mAttachedToWindow && types != 0) { 1300abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown mRouter.addCallback(types, mCallback, 1310abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown MediaRouter.CALLBACK_FLAG_PASSIVE_DISCOVERY); 1320abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown } 1330abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown 1340abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown refreshRoute(); 135690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 1360abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown } 137690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 1380abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown public void setExtendedSettingsClickListener(OnClickListener listener) { 1390abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown mExtendedSettingsClickListener = listener; 140690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 141690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 1420abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown /** 1430abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * Show the route chooser or controller dialog. 1440abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * <p> 1450abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * If the default route is selected or if the currently selected route does 1460abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * not match the {@link #getRouteTypes route types}, then shows the route chooser dialog. 1470abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * Otherwise, shows the route controller dialog to offer the user 1480abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * a choice to disconnect from the route or perform other control actions 1490abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * such as setting the route's volume. 1500abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * </p><p> 1510abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * This will attach a {@link DialogFragment} to the containing Activity. 1520abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * </p> 1530abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown */ 1540abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown public void showDialog() { 1550abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown showDialogInternal(); 1560abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown } 1570abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown 1580abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown boolean showDialogInternal() { 1590abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown if (!mAttachedToWindow) { 1600abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown return false; 161690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 162690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 1630abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown DialogFragment f = MediaRouteDialogPresenter.showDialogFragment(getActivity(), 1640abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown mRouteTypes, mExtendedSettingsClickListener); 1650abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown return f != null; 1660abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown } 1670abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown 1680abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown private Activity getActivity() { 1690abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown // Gross way of unwrapping the Activity so we can get the FragmentManager 1700abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown Context context = getContext(); 1710abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown while (context instanceof ContextWrapper) { 1720abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown if (context instanceof Activity) { 1730abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown return (Activity)context; 174690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 1750abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown context = ((ContextWrapper)context).getBaseContext(); 176690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 1770abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown throw new IllegalStateException("The MediaRouteButton's Context is not an Activity."); 178690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 179690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 1800abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown /** 1810abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * Sets whether to enable showing a toast with the content descriptor of the 1820abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * button when the button is long pressed. 1830abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown */ 184e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell void setCheatSheetEnabled(boolean enable) { 185e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell mCheatSheetEnabled = enable; 186e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell } 187e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell 188e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell @Override 1890abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown public boolean performClick() { 1900abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown // Send the appropriate accessibility events and call listeners 1910abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown boolean handled = super.performClick(); 1920abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown if (!handled) { 1930abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown playSoundEffect(SoundEffectConstants.CLICK); 1940abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown } 1950abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown return showDialogInternal() || handled; 1960abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown } 1970abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown 1980abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown @Override 199e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell public boolean performLongClick() { 200e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell if (super.performLongClick()) { 201e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell return true; 202e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell } 203e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell 204e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell if (!mCheatSheetEnabled) { 205e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell return false; 206e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell } 207e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell 208e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell final CharSequence contentDesc = getContentDescription(); 209e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell if (TextUtils.isEmpty(contentDesc)) { 210e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell // Don't show the cheat sheet if we have no description 211e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell return false; 212e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell } 213e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell 214e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell final int[] screenPos = new int[2]; 215e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell final Rect displayFrame = new Rect(); 216e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell getLocationOnScreen(screenPos); 217e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell getWindowVisibleDisplayFrame(displayFrame); 218e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell 219e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell final Context context = getContext(); 220e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell final int width = getWidth(); 221e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell final int height = getHeight(); 222e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell final int midy = screenPos[1] + height / 2; 223e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell final int screenWidth = context.getResources().getDisplayMetrics().widthPixels; 224e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell 225e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell Toast cheatSheet = Toast.makeText(context, contentDesc, Toast.LENGTH_SHORT); 226e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell if (midy < displayFrame.height()) { 227e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell // Show along the top; follow action buttons 228e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell cheatSheet.setGravity(Gravity.TOP | Gravity.END, 229e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell screenWidth - screenPos[0] - width / 2, height); 230e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell } else { 231e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell // Show along the bottom center 232e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height); 233e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell } 234e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell cheatSheet.show(); 235e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); 236e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell return true; 237e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell } 238e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell 239690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 240690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell protected int[] onCreateDrawableState(int extraSpace) { 241690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 2422ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell 2432ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell // Technically we should be handling this more completely, but these 2442ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell // are implementation details here. Checked is used to express the connecting 2452ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell // drawable state and it's mutually exclusive with activated for the purposes 2462ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell // of state selection here. 2472ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell if (mIsConnecting) { 2482ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell mergeDrawableStates(drawableState, CHECKED_STATE_SET); 2492ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell } else if (mRemoteActive) { 250690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mergeDrawableStates(drawableState, ACTIVATED_STATE_SET); 251690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 252690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell return drawableState; 253690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 254690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 255690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 256690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell protected void drawableStateChanged() { 257690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell super.drawableStateChanged(); 258690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 259690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (mRemoteIndicator != null) { 260690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell int[] myDrawableState = getDrawableState(); 261690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mRemoteIndicator.setState(myDrawableState); 262690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell invalidate(); 263690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 264690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 265690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 2660abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown private void setRemoteIndicatorDrawable(Drawable d) { 2670abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown if (mRemoteIndicator != null) { 2680abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown mRemoteIndicator.setCallback(null); 2690abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown unscheduleDrawable(mRemoteIndicator); 2700abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown } 2710abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown mRemoteIndicator = d; 2720abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown if (d != null) { 2730abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown d.setCallback(this); 2740abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown d.setState(getDrawableState()); 2750abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown d.setVisible(getVisibility() == VISIBLE, false); 2760abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown } 2770abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown 2780abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown refreshDrawableState(); 2790abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown } 2800abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown 281690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 282690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell protected boolean verifyDrawable(Drawable who) { 283690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell return super.verifyDrawable(who) || who == mRemoteIndicator; 284690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 285690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 286690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 287690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public void jumpDrawablesToCurrentState() { 288690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell super.jumpDrawablesToCurrentState(); 2890abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown 2900abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown if (mRemoteIndicator != null) { 2910abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown mRemoteIndicator.jumpToCurrentState(); 2920abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown } 293690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 294690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 295690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 296690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public void setVisibility(int visibility) { 297690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell super.setVisibility(visibility); 2980abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown 299690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (mRemoteIndicator != null) { 300690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mRemoteIndicator.setVisible(getVisibility() == VISIBLE, false); 301690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 302690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 303690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 304690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 305101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich public void onAttachedToWindow() { 306101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich super.onAttachedToWindow(); 3070abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown 308101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich mAttachedToWindow = true; 309101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich if (mRouteTypes != 0) { 3100abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown mRouter.addCallback(mRouteTypes, mCallback, 31169b07161bebdb2c726e3a826c2268866f1a94517Jeff Brown MediaRouter.CALLBACK_FLAG_PASSIVE_DISCOVERY); 312101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich } 3130abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown refreshRoute(); 314101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich } 315101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich 316101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich @Override 317101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich public void onDetachedFromWindow() { 3180abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown mAttachedToWindow = false; 319101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich if (mRouteTypes != 0) { 3200abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown mRouter.removeCallback(mCallback); 321101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich } 3220abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown 323101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich super.onDetachedFromWindow(); 324101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich } 325101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich 326101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich @Override 327690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 328690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int widthSize = MeasureSpec.getSize(widthMeasureSpec); 329690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int heightSize = MeasureSpec.getSize(heightMeasureSpec); 330690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 331690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 332690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 333de0d5d746fc030770b64858b64eac2b1c26e4ba6Dongwon Kang final int width = Math.max(mMinWidth, mRemoteIndicator != null ? 334de0d5d746fc030770b64858b64eac2b1c26e4ba6Dongwon Kang mRemoteIndicator.getIntrinsicWidth() + getPaddingLeft() + getPaddingRight() : 0); 335de0d5d746fc030770b64858b64eac2b1c26e4ba6Dongwon Kang final int height = Math.max(mMinHeight, mRemoteIndicator != null ? 336de0d5d746fc030770b64858b64eac2b1c26e4ba6Dongwon Kang mRemoteIndicator.getIntrinsicHeight() + getPaddingTop() + getPaddingBottom() : 0); 337690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 338de0d5d746fc030770b64858b64eac2b1c26e4ba6Dongwon Kang int measuredWidth; 339690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell switch (widthMode) { 340690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell case MeasureSpec.EXACTLY: 341de0d5d746fc030770b64858b64eac2b1c26e4ba6Dongwon Kang measuredWidth = widthSize; 342690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell break; 343690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell case MeasureSpec.AT_MOST: 344de0d5d746fc030770b64858b64eac2b1c26e4ba6Dongwon Kang measuredWidth = Math.min(widthSize, width); 345690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell break; 346690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell default: 347690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell case MeasureSpec.UNSPECIFIED: 348de0d5d746fc030770b64858b64eac2b1c26e4ba6Dongwon Kang measuredWidth = width; 349690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell break; 350690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 351690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 352de0d5d746fc030770b64858b64eac2b1c26e4ba6Dongwon Kang int measuredHeight; 353690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell switch (heightMode) { 354690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell case MeasureSpec.EXACTLY: 355de0d5d746fc030770b64858b64eac2b1c26e4ba6Dongwon Kang measuredHeight = heightSize; 356690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell break; 357690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell case MeasureSpec.AT_MOST: 358de0d5d746fc030770b64858b64eac2b1c26e4ba6Dongwon Kang measuredHeight = Math.min(heightSize, height); 359690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell break; 360690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell default: 361690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell case MeasureSpec.UNSPECIFIED: 362de0d5d746fc030770b64858b64eac2b1c26e4ba6Dongwon Kang measuredHeight = height; 363690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell break; 364690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 365690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 366de0d5d746fc030770b64858b64eac2b1c26e4ba6Dongwon Kang setMeasuredDimension(measuredWidth, measuredHeight); 367690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 368690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 369690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 370690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell protected void onDraw(Canvas canvas) { 371690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell super.onDraw(canvas); 372690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 373690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (mRemoteIndicator == null) return; 374690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 375690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int left = getPaddingLeft(); 376690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int right = getWidth() - getPaddingRight(); 377690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int top = getPaddingTop(); 378690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int bottom = getHeight() - getPaddingBottom(); 379690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 380690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int drawWidth = mRemoteIndicator.getIntrinsicWidth(); 381690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int drawHeight = mRemoteIndicator.getIntrinsicHeight(); 382690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int drawLeft = left + (right - left - drawWidth) / 2; 383690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int drawTop = top + (bottom - top - drawHeight) / 2; 384690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 3850abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown mRemoteIndicator.setBounds(drawLeft, drawTop, 3860abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown drawLeft + drawWidth, drawTop + drawHeight); 387690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mRemoteIndicator.draw(canvas); 388690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 389690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 3900abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown private void refreshRoute() { 3910abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown if (mAttachedToWindow) { 3920abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown final MediaRouter.RouteInfo route = mRouter.getSelectedRoute(); 3930abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown final boolean isRemote = !route.isDefault() && route.matchesTypes(mRouteTypes); 3940abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown final boolean isConnecting = isRemote && route.isConnecting(); 3950abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown 3960abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown boolean needsRefresh = false; 3970abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown if (mRemoteActive != isRemote) { 3980abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown mRemoteActive = isRemote; 3990abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown needsRefresh = true; 4000abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown } 4010abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown if (mIsConnecting != isConnecting) { 4020abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown mIsConnecting = isConnecting; 4030abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown needsRefresh = true; 4040abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown } 40570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 4060abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown if (needsRefresh) { 4070abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown refreshDrawableState(); 40870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 40970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 4100abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown setEnabled(mRouter.isRouteAvailable(mRouteTypes, 4110abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown MediaRouter.AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE)); 41270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 413b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell } 414b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell 4150abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown private final class MediaRouterCallback extends MediaRouter.SimpleCallback { 416690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 4170abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown public void onRouteAdded(MediaRouter router, RouteInfo info) { 4180abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown refreshRoute(); 419690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 420690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 421690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 4220abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown public void onRouteRemoved(MediaRouter router, RouteInfo info) { 4230abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown refreshRoute(); 424690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 425690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 426690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 4272ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell public void onRouteChanged(MediaRouter router, RouteInfo info) { 4280abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown refreshRoute(); 4292ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell } 4302ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell 4312ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell @Override 4320abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown public void onRouteSelected(MediaRouter router, int type, RouteInfo info) { 4330abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown refreshRoute(); 434690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 435690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 436690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 4370abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) { 4380abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown refreshRoute(); 439690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 440f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell 441f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell @Override 442f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell public void onRouteGrouped(MediaRouter router, RouteInfo info, RouteGroup group, 443f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell int index) { 4440abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown refreshRoute(); 445f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell } 446f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell 447f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell @Override 448f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group) { 4490abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown refreshRoute(); 450f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell } 451690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 452690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell} 453