MediaRouteButton.java revision eff7719415542ba819054863b0995f07742a7a8a
111417b1cfde8f1749905f2d735623af9214148afJeff Brown/* 211417b1cfde8f1749905f2d735623af9214148afJeff Brown * Copyright (C) 2013 The Android Open Source Project 311417b1cfde8f1749905f2d735623af9214148afJeff Brown * 411417b1cfde8f1749905f2d735623af9214148afJeff Brown * Licensed under the Apache License, Version 2.0 (the "License"); 511417b1cfde8f1749905f2d735623af9214148afJeff Brown * you may not use this file except in compliance with the License. 611417b1cfde8f1749905f2d735623af9214148afJeff Brown * You may obtain a copy of the License at 711417b1cfde8f1749905f2d735623af9214148afJeff Brown * 811417b1cfde8f1749905f2d735623af9214148afJeff Brown * http://www.apache.org/licenses/LICENSE-2.0 911417b1cfde8f1749905f2d735623af9214148afJeff Brown * 1011417b1cfde8f1749905f2d735623af9214148afJeff Brown * Unless required by applicable law or agreed to in writing, software 1111417b1cfde8f1749905f2d735623af9214148afJeff Brown * distributed under the License is distributed on an "AS IS" BASIS, 1211417b1cfde8f1749905f2d735623af9214148afJeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1311417b1cfde8f1749905f2d735623af9214148afJeff Brown * See the License for the specific language governing permissions and 1411417b1cfde8f1749905f2d735623af9214148afJeff Brown * limitations under the License. 1511417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 1611417b1cfde8f1749905f2d735623af9214148afJeff Brown 1711417b1cfde8f1749905f2d735623af9214148afJeff Brownpackage android.support.v7.app; 1811417b1cfde8f1749905f2d735623af9214148afJeff Brown 1911417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.app.Activity; 2011417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.content.Context; 2111417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.content.ContextWrapper; 2211417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.content.res.TypedArray; 2311417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.graphics.Canvas; 2411417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.graphics.Rect; 2511417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.graphics.drawable.Drawable; 2611417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v4.app.FragmentActivity; 2711417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v4.app.FragmentManager; 2811417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v4.graphics.drawable.DrawableCompat; 2911417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v4.view.GravityCompat; 3011417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouter; 3111417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouteSelector; 3211417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.mediarouter.R; 3311417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.text.TextUtils; 3411417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.util.AttributeSet; 3511417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.util.Log; 3611417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.Gravity; 3711417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.HapticFeedbackConstants; 3811417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.SoundEffectConstants; 3911417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.View; 4011417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.Toast; 4111417b1cfde8f1749905f2d735623af9214148afJeff Brown 4211417b1cfde8f1749905f2d735623af9214148afJeff Brown/** 4311417b1cfde8f1749905f2d735623af9214148afJeff Brown * The media route button allows the user to select routes and to control the 4411417b1cfde8f1749905f2d735623af9214148afJeff Brown * currently selected route. 459942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * <p> 469942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * The application must specify the kinds of routes that the user should be allowed 479942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * to select by specifying a {@link MediaRouteSelector selector} with the 489942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * {@link #setRouteSelector} method. 499942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * </p><p> 509942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * When the default route is selected or when the currently selected route does not 519942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * match the {@link #getRouteSelector() selector}, the button will appear in 529942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * an inactive state indicating that the application is not connected to a 539942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * route of the kind that it wants to use. Clicking on the button opens 549942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * a {@link MediaRouteChooserDialog} to allow the user to select a route. 559942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * If no non-default routes match the selector and it is not possible for an active 569942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * scan to discover any matching routes, then the button is disabled and cannot 579942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * be clicked. 589942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * </p><p> 599942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * When a non-default route is selected that matches the selector, the button will 609942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * appear in an active state indicating that the application is connected 619942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * to a route of the kind that it wants to use. The button may also appear 629942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * in an intermediary connecting state if the route is in the process of connecting 639942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * to the destination but has not yet completed doing so. In either case, clicking 649942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * on the button opens a {@link MediaRouteControllerDialog} to allow the user 659942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * to control or disconnect from the current route. 669942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * </p> 6711417b1cfde8f1749905f2d735623af9214148afJeff Brown * 6811417b1cfde8f1749905f2d735623af9214148afJeff Brown * <h3>Prerequisites</h3> 6911417b1cfde8f1749905f2d735623af9214148afJeff Brown * <p> 7011417b1cfde8f1749905f2d735623af9214148afJeff Brown * To use the media route button, the activity must be a subclass of 7111417b1cfde8f1749905f2d735623af9214148afJeff Brown * {@link FragmentActivity} from the <code>android.support.v4</code> 7211417b1cfde8f1749905f2d735623af9214148afJeff Brown * support library. Refer to support library documentation for details. 7311417b1cfde8f1749905f2d735623af9214148afJeff Brown * </p> 7411417b1cfde8f1749905f2d735623af9214148afJeff Brown * 7511417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see MediaRouteActionProvider 7611417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see #setRouteSelector 7711417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 7811417b1cfde8f1749905f2d735623af9214148afJeff Brownpublic class MediaRouteButton extends View { 7911417b1cfde8f1749905f2d735623af9214148afJeff Brown private static final String TAG = "MediaRouteButton"; 8011417b1cfde8f1749905f2d735623af9214148afJeff Brown 8111417b1cfde8f1749905f2d735623af9214148afJeff Brown private static final String CHOOSER_FRAGMENT_TAG = 8211417b1cfde8f1749905f2d735623af9214148afJeff Brown "android.support.v7.mediarouter:MediaRouteChooserDialogFragment"; 8311417b1cfde8f1749905f2d735623af9214148afJeff Brown private static final String CONTROLLER_FRAGMENT_TAG = 8411417b1cfde8f1749905f2d735623af9214148afJeff Brown "android.support.v7.mediarouter:MediaRouteControllerDialogFragment"; 8511417b1cfde8f1749905f2d735623af9214148afJeff Brown 8611417b1cfde8f1749905f2d735623af9214148afJeff Brown private final MediaRouter mRouter; 8711417b1cfde8f1749905f2d735623af9214148afJeff Brown private final MediaRouterCallback mCallback; 8811417b1cfde8f1749905f2d735623af9214148afJeff Brown 8911417b1cfde8f1749905f2d735623af9214148afJeff Brown private MediaRouteSelector mSelector = MediaRouteSelector.EMPTY; 90eff7719415542ba819054863b0995f07742a7a8aJeff Brown private MediaRouteDialogFactory mDialogFactory = MediaRouteDialogFactory.getDefault(); 9111417b1cfde8f1749905f2d735623af9214148afJeff Brown 9211417b1cfde8f1749905f2d735623af9214148afJeff Brown private boolean mAttachedToWindow; 9311417b1cfde8f1749905f2d735623af9214148afJeff Brown 9411417b1cfde8f1749905f2d735623af9214148afJeff Brown private Drawable mRemoteIndicator; 9511417b1cfde8f1749905f2d735623af9214148afJeff Brown private boolean mRemoteActive; 9611417b1cfde8f1749905f2d735623af9214148afJeff Brown private boolean mCheatSheetEnabled; 9711417b1cfde8f1749905f2d735623af9214148afJeff Brown private boolean mIsConnecting; 9811417b1cfde8f1749905f2d735623af9214148afJeff Brown 9911417b1cfde8f1749905f2d735623af9214148afJeff Brown private int mMinWidth; 10011417b1cfde8f1749905f2d735623af9214148afJeff Brown private int mMinHeight; 10111417b1cfde8f1749905f2d735623af9214148afJeff Brown 10211417b1cfde8f1749905f2d735623af9214148afJeff Brown // The checked state is used when connected to a remote route. 10311417b1cfde8f1749905f2d735623af9214148afJeff Brown private static final int[] CHECKED_STATE_SET = { 10411417b1cfde8f1749905f2d735623af9214148afJeff Brown android.R.attr.state_checked 10511417b1cfde8f1749905f2d735623af9214148afJeff Brown }; 10611417b1cfde8f1749905f2d735623af9214148afJeff Brown 10711417b1cfde8f1749905f2d735623af9214148afJeff Brown // The checkable state is used while connecting to a remote route. 10811417b1cfde8f1749905f2d735623af9214148afJeff Brown private static final int[] CHECKABLE_STATE_SET = { 10911417b1cfde8f1749905f2d735623af9214148afJeff Brown android.R.attr.state_checkable 11011417b1cfde8f1749905f2d735623af9214148afJeff Brown }; 11111417b1cfde8f1749905f2d735623af9214148afJeff Brown 11211417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouteButton(Context context) { 11311417b1cfde8f1749905f2d735623af9214148afJeff Brown this(context, null); 11411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 11511417b1cfde8f1749905f2d735623af9214148afJeff Brown 11611417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouteButton(Context context, AttributeSet attrs) { 11711417b1cfde8f1749905f2d735623af9214148afJeff Brown this(context, attrs, R.attr.mediaRouteButtonStyle); 11811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 11911417b1cfde8f1749905f2d735623af9214148afJeff Brown 12011417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouteButton(Context context, AttributeSet attrs, int defStyleAttr) { 1219942d40d0d952b03b583fe66f434676793697aa2Jeff Brown super(MediaRouterThemeHelper.createThemedContext(context, false), attrs, defStyleAttr); 12211417b1cfde8f1749905f2d735623af9214148afJeff Brown context = getContext(); 12311417b1cfde8f1749905f2d735623af9214148afJeff Brown 12411417b1cfde8f1749905f2d735623af9214148afJeff Brown mRouter = MediaRouter.getInstance(context); 12511417b1cfde8f1749905f2d735623af9214148afJeff Brown mCallback = new MediaRouterCallback(); 12611417b1cfde8f1749905f2d735623af9214148afJeff Brown 12711417b1cfde8f1749905f2d735623af9214148afJeff Brown TypedArray a = context.obtainStyledAttributes(attrs, 12811417b1cfde8f1749905f2d735623af9214148afJeff Brown R.styleable.MediaRouteButton, defStyleAttr, 0); 12911417b1cfde8f1749905f2d735623af9214148afJeff Brown setRemoteIndicatorDrawable(a.getDrawable( 13011417b1cfde8f1749905f2d735623af9214148afJeff Brown R.styleable.MediaRouteButton_externalRouteEnabledDrawable)); 13111417b1cfde8f1749905f2d735623af9214148afJeff Brown mMinWidth = a.getDimensionPixelSize( 13211417b1cfde8f1749905f2d735623af9214148afJeff Brown R.styleable.MediaRouteButton_android_minWidth, 0); 13311417b1cfde8f1749905f2d735623af9214148afJeff Brown mMinHeight = a.getDimensionPixelSize( 13411417b1cfde8f1749905f2d735623af9214148afJeff Brown R.styleable.MediaRouteButton_android_minHeight, 0); 13511417b1cfde8f1749905f2d735623af9214148afJeff Brown a.recycle(); 13611417b1cfde8f1749905f2d735623af9214148afJeff Brown 13711417b1cfde8f1749905f2d735623af9214148afJeff Brown setClickable(true); 13811417b1cfde8f1749905f2d735623af9214148afJeff Brown setLongClickable(true); 13911417b1cfde8f1749905f2d735623af9214148afJeff Brown } 14011417b1cfde8f1749905f2d735623af9214148afJeff Brown 14111417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 14211417b1cfde8f1749905f2d735623af9214148afJeff Brown * Gets the media route selector for filtering the routes that the user can 14311417b1cfde8f1749905f2d735623af9214148afJeff Brown * select using the media route chooser dialog. 14411417b1cfde8f1749905f2d735623af9214148afJeff Brown * 14511417b1cfde8f1749905f2d735623af9214148afJeff Brown * @return The selector, never null. 14611417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 14711417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouteSelector getRouteSelector() { 14811417b1cfde8f1749905f2d735623af9214148afJeff Brown return mSelector; 14911417b1cfde8f1749905f2d735623af9214148afJeff Brown } 15011417b1cfde8f1749905f2d735623af9214148afJeff Brown 15111417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 15211417b1cfde8f1749905f2d735623af9214148afJeff Brown * Sets the media route selector for filtering the routes that the user can 15311417b1cfde8f1749905f2d735623af9214148afJeff Brown * select using the media route chooser dialog. 15411417b1cfde8f1749905f2d735623af9214148afJeff Brown * 15511417b1cfde8f1749905f2d735623af9214148afJeff Brown * @param selector The selector, must not be null. 15611417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 15711417b1cfde8f1749905f2d735623af9214148afJeff Brown public void setRouteSelector(MediaRouteSelector selector) { 15811417b1cfde8f1749905f2d735623af9214148afJeff Brown if (selector == null) { 15911417b1cfde8f1749905f2d735623af9214148afJeff Brown throw new IllegalArgumentException("selector must not be null"); 16011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 16111417b1cfde8f1749905f2d735623af9214148afJeff Brown 16211417b1cfde8f1749905f2d735623af9214148afJeff Brown if (!mSelector.equals(selector)) { 16311417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mAttachedToWindow) { 1649942d40d0d952b03b583fe66f434676793697aa2Jeff Brown if (!mSelector.isEmpty()) { 1659942d40d0d952b03b583fe66f434676793697aa2Jeff Brown mRouter.removeCallback(mCallback); 1669942d40d0d952b03b583fe66f434676793697aa2Jeff Brown } 1679942d40d0d952b03b583fe66f434676793697aa2Jeff Brown if (!selector.isEmpty()) { 1689942d40d0d952b03b583fe66f434676793697aa2Jeff Brown mRouter.addCallback(selector, mCallback); 1699942d40d0d952b03b583fe66f434676793697aa2Jeff Brown } 17011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 1719942d40d0d952b03b583fe66f434676793697aa2Jeff Brown mSelector = selector; 17211417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 17311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 17411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 17511417b1cfde8f1749905f2d735623af9214148afJeff Brown 17611417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 177eff7719415542ba819054863b0995f07742a7a8aJeff Brown * Gets the media route dialog factory to use when showing the route chooser 178eff7719415542ba819054863b0995f07742a7a8aJeff Brown * or controller dialog. 179eff7719415542ba819054863b0995f07742a7a8aJeff Brown * 180eff7719415542ba819054863b0995f07742a7a8aJeff Brown * @return The dialog factory, never null. 181eff7719415542ba819054863b0995f07742a7a8aJeff Brown */ 182eff7719415542ba819054863b0995f07742a7a8aJeff Brown public MediaRouteDialogFactory getDialogFactory() { 183eff7719415542ba819054863b0995f07742a7a8aJeff Brown return mDialogFactory; 184eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 185eff7719415542ba819054863b0995f07742a7a8aJeff Brown 186eff7719415542ba819054863b0995f07742a7a8aJeff Brown /** 187eff7719415542ba819054863b0995f07742a7a8aJeff Brown * Sets the media route dialog factory to use when showing the route chooser 188eff7719415542ba819054863b0995f07742a7a8aJeff Brown * or controller dialog. 189eff7719415542ba819054863b0995f07742a7a8aJeff Brown * 190eff7719415542ba819054863b0995f07742a7a8aJeff Brown * @param factory The dialog factory, must not be null. 191eff7719415542ba819054863b0995f07742a7a8aJeff Brown */ 192eff7719415542ba819054863b0995f07742a7a8aJeff Brown public void setDialogFactory(MediaRouteDialogFactory factory) { 193eff7719415542ba819054863b0995f07742a7a8aJeff Brown if (factory == null) { 194eff7719415542ba819054863b0995f07742a7a8aJeff Brown throw new IllegalArgumentException("factory must not be null"); 195eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 196eff7719415542ba819054863b0995f07742a7a8aJeff Brown 197eff7719415542ba819054863b0995f07742a7a8aJeff Brown mDialogFactory = factory; 198eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 199eff7719415542ba819054863b0995f07742a7a8aJeff Brown 200eff7719415542ba819054863b0995f07742a7a8aJeff Brown /** 20111417b1cfde8f1749905f2d735623af9214148afJeff Brown * Show the route chooser or controller dialog. 20211417b1cfde8f1749905f2d735623af9214148afJeff Brown * <p> 2039942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * If the default route is selected or if the currently selected route does 2049942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * not match the {@link #getRouteSelector selector}, then shows the route chooser dialog. 2059942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * Otherwise, shows the route controller dialog to offer the user 20611417b1cfde8f1749905f2d735623af9214148afJeff Brown * a choice to disconnect from the route or perform other control actions 20711417b1cfde8f1749905f2d735623af9214148afJeff Brown * such as setting the route's volume. 2089942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * </p><p> 209eff7719415542ba819054863b0995f07742a7a8aJeff Brown * The application can customize the dialogs by calling {@link #setDialogFactory} 210eff7719415542ba819054863b0995f07742a7a8aJeff Brown * to provide a customized dialog factory. 21111417b1cfde8f1749905f2d735623af9214148afJeff Brown * </p> 21211417b1cfde8f1749905f2d735623af9214148afJeff Brown * 21311417b1cfde8f1749905f2d735623af9214148afJeff Brown * @return True if the dialog was actually shown. 21411417b1cfde8f1749905f2d735623af9214148afJeff Brown * 21511417b1cfde8f1749905f2d735623af9214148afJeff Brown * @throws IllegalStateException if the activity is not a subclass of 21611417b1cfde8f1749905f2d735623af9214148afJeff Brown * {@link FragmentActivity}. 21711417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 21811417b1cfde8f1749905f2d735623af9214148afJeff Brown public boolean showDialog() { 21911417b1cfde8f1749905f2d735623af9214148afJeff Brown if (!mAttachedToWindow) { 22011417b1cfde8f1749905f2d735623af9214148afJeff Brown return false; 22111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 22211417b1cfde8f1749905f2d735623af9214148afJeff Brown 22311417b1cfde8f1749905f2d735623af9214148afJeff Brown final FragmentManager fm = getFragmentManager(); 22411417b1cfde8f1749905f2d735623af9214148afJeff Brown if (fm == null) { 22511417b1cfde8f1749905f2d735623af9214148afJeff Brown throw new IllegalStateException("The activity must be a subclass of FragmentActivity"); 22611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 22711417b1cfde8f1749905f2d735623af9214148afJeff Brown 2289942d40d0d952b03b583fe66f434676793697aa2Jeff Brown MediaRouter.RouteInfo route = mRouter.getSelectedRoute(); 2299942d40d0d952b03b583fe66f434676793697aa2Jeff Brown if (route.isDefault() || !route.matchesSelector(mSelector)) { 23011417b1cfde8f1749905f2d735623af9214148afJeff Brown if (fm.findFragmentByTag(CHOOSER_FRAGMENT_TAG) != null) { 23111417b1cfde8f1749905f2d735623af9214148afJeff Brown Log.w(TAG, "showDialog(): Route chooser dialog already showing!"); 23211417b1cfde8f1749905f2d735623af9214148afJeff Brown return false; 23311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 234eff7719415542ba819054863b0995f07742a7a8aJeff Brown MediaRouteChooserDialogFragment f = 235eff7719415542ba819054863b0995f07742a7a8aJeff Brown mDialogFactory.onCreateChooserDialogFragment(); 23611417b1cfde8f1749905f2d735623af9214148afJeff Brown f.setRouteSelector(mSelector); 23711417b1cfde8f1749905f2d735623af9214148afJeff Brown f.show(fm, CHOOSER_FRAGMENT_TAG); 23811417b1cfde8f1749905f2d735623af9214148afJeff Brown } else { 23911417b1cfde8f1749905f2d735623af9214148afJeff Brown if (fm.findFragmentByTag(CONTROLLER_FRAGMENT_TAG) != null) { 24011417b1cfde8f1749905f2d735623af9214148afJeff Brown Log.w(TAG, "showDialog(): Route controller dialog already showing!"); 24111417b1cfde8f1749905f2d735623af9214148afJeff Brown return false; 24211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 243eff7719415542ba819054863b0995f07742a7a8aJeff Brown MediaRouteControllerDialogFragment f = 244eff7719415542ba819054863b0995f07742a7a8aJeff Brown mDialogFactory.onCreateControllerDialogFragment(); 24511417b1cfde8f1749905f2d735623af9214148afJeff Brown f.show(fm, CONTROLLER_FRAGMENT_TAG); 24611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 24711417b1cfde8f1749905f2d735623af9214148afJeff Brown return true; 24811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 24911417b1cfde8f1749905f2d735623af9214148afJeff Brown 25011417b1cfde8f1749905f2d735623af9214148afJeff Brown private FragmentManager getFragmentManager() { 25111417b1cfde8f1749905f2d735623af9214148afJeff Brown Activity activity = getActivity(); 25211417b1cfde8f1749905f2d735623af9214148afJeff Brown if (activity instanceof FragmentActivity) { 25311417b1cfde8f1749905f2d735623af9214148afJeff Brown return ((FragmentActivity)activity).getSupportFragmentManager(); 25411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 25511417b1cfde8f1749905f2d735623af9214148afJeff Brown return null; 25611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 25711417b1cfde8f1749905f2d735623af9214148afJeff Brown 25811417b1cfde8f1749905f2d735623af9214148afJeff Brown private Activity getActivity() { 25911417b1cfde8f1749905f2d735623af9214148afJeff Brown // Gross way of unwrapping the Activity so we can get the FragmentManager 26011417b1cfde8f1749905f2d735623af9214148afJeff Brown Context context = getContext(); 26111417b1cfde8f1749905f2d735623af9214148afJeff Brown while (context instanceof ContextWrapper) { 26211417b1cfde8f1749905f2d735623af9214148afJeff Brown if (context instanceof Activity) { 26311417b1cfde8f1749905f2d735623af9214148afJeff Brown return (Activity)context; 26411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 26511417b1cfde8f1749905f2d735623af9214148afJeff Brown context = ((ContextWrapper)context).getBaseContext(); 26611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 26711417b1cfde8f1749905f2d735623af9214148afJeff Brown return null; 26811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 26911417b1cfde8f1749905f2d735623af9214148afJeff Brown 27011417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 27111417b1cfde8f1749905f2d735623af9214148afJeff Brown * Sets whether to enable showing a toast with the content descriptor of the 27211417b1cfde8f1749905f2d735623af9214148afJeff Brown * button when the button is long pressed. 27311417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 27411417b1cfde8f1749905f2d735623af9214148afJeff Brown void setCheatSheetEnabled(boolean enable) { 27511417b1cfde8f1749905f2d735623af9214148afJeff Brown mCheatSheetEnabled = enable; 27611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 27711417b1cfde8f1749905f2d735623af9214148afJeff Brown 27811417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 27911417b1cfde8f1749905f2d735623af9214148afJeff Brown public boolean performClick() { 28011417b1cfde8f1749905f2d735623af9214148afJeff Brown // Send the appropriate accessibility events and call listeners 28111417b1cfde8f1749905f2d735623af9214148afJeff Brown boolean handled = super.performClick(); 28211417b1cfde8f1749905f2d735623af9214148afJeff Brown if (!handled) { 28311417b1cfde8f1749905f2d735623af9214148afJeff Brown playSoundEffect(SoundEffectConstants.CLICK); 28411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 28511417b1cfde8f1749905f2d735623af9214148afJeff Brown return showDialog() || handled; 28611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 28711417b1cfde8f1749905f2d735623af9214148afJeff Brown 28811417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 28911417b1cfde8f1749905f2d735623af9214148afJeff Brown public boolean performLongClick() { 29011417b1cfde8f1749905f2d735623af9214148afJeff Brown if (super.performLongClick()) { 29111417b1cfde8f1749905f2d735623af9214148afJeff Brown return true; 29211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 29311417b1cfde8f1749905f2d735623af9214148afJeff Brown 29411417b1cfde8f1749905f2d735623af9214148afJeff Brown if (!mCheatSheetEnabled) { 29511417b1cfde8f1749905f2d735623af9214148afJeff Brown return false; 29611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 29711417b1cfde8f1749905f2d735623af9214148afJeff Brown 29811417b1cfde8f1749905f2d735623af9214148afJeff Brown final CharSequence contentDesc = getContentDescription(); 29911417b1cfde8f1749905f2d735623af9214148afJeff Brown if (TextUtils.isEmpty(contentDesc)) { 30011417b1cfde8f1749905f2d735623af9214148afJeff Brown // Don't show the cheat sheet if we have no description 30111417b1cfde8f1749905f2d735623af9214148afJeff Brown return false; 30211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 30311417b1cfde8f1749905f2d735623af9214148afJeff Brown 30411417b1cfde8f1749905f2d735623af9214148afJeff Brown final int[] screenPos = new int[2]; 30511417b1cfde8f1749905f2d735623af9214148afJeff Brown final Rect displayFrame = new Rect(); 30611417b1cfde8f1749905f2d735623af9214148afJeff Brown getLocationOnScreen(screenPos); 30711417b1cfde8f1749905f2d735623af9214148afJeff Brown getWindowVisibleDisplayFrame(displayFrame); 30811417b1cfde8f1749905f2d735623af9214148afJeff Brown 30911417b1cfde8f1749905f2d735623af9214148afJeff Brown final Context context = getContext(); 31011417b1cfde8f1749905f2d735623af9214148afJeff Brown final int width = getWidth(); 31111417b1cfde8f1749905f2d735623af9214148afJeff Brown final int height = getHeight(); 31211417b1cfde8f1749905f2d735623af9214148afJeff Brown final int midy = screenPos[1] + height / 2; 31311417b1cfde8f1749905f2d735623af9214148afJeff Brown final int screenWidth = context.getResources().getDisplayMetrics().widthPixels; 31411417b1cfde8f1749905f2d735623af9214148afJeff Brown 31511417b1cfde8f1749905f2d735623af9214148afJeff Brown Toast cheatSheet = Toast.makeText(context, contentDesc, Toast.LENGTH_SHORT); 31611417b1cfde8f1749905f2d735623af9214148afJeff Brown if (midy < displayFrame.height()) { 31711417b1cfde8f1749905f2d735623af9214148afJeff Brown // Show along the top; follow action buttons 31811417b1cfde8f1749905f2d735623af9214148afJeff Brown cheatSheet.setGravity(Gravity.TOP | GravityCompat.END, 31911417b1cfde8f1749905f2d735623af9214148afJeff Brown screenWidth - screenPos[0] - width / 2, height); 32011417b1cfde8f1749905f2d735623af9214148afJeff Brown } else { 32111417b1cfde8f1749905f2d735623af9214148afJeff Brown // Show along the bottom center 32211417b1cfde8f1749905f2d735623af9214148afJeff Brown cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height); 32311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 32411417b1cfde8f1749905f2d735623af9214148afJeff Brown cheatSheet.show(); 32511417b1cfde8f1749905f2d735623af9214148afJeff Brown performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); 32611417b1cfde8f1749905f2d735623af9214148afJeff Brown return true; 32711417b1cfde8f1749905f2d735623af9214148afJeff Brown } 32811417b1cfde8f1749905f2d735623af9214148afJeff Brown 32911417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 33011417b1cfde8f1749905f2d735623af9214148afJeff Brown protected int[] onCreateDrawableState(int extraSpace) { 33111417b1cfde8f1749905f2d735623af9214148afJeff Brown final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 33211417b1cfde8f1749905f2d735623af9214148afJeff Brown 33311417b1cfde8f1749905f2d735623af9214148afJeff Brown // Technically we should be handling this more completely, but these 33411417b1cfde8f1749905f2d735623af9214148afJeff Brown // are implementation details here. Checkable is used to express the connecting 33511417b1cfde8f1749905f2d735623af9214148afJeff Brown // drawable state and it's mutually exclusive with check for the purposes 33611417b1cfde8f1749905f2d735623af9214148afJeff Brown // of state selection here. 33711417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mIsConnecting) { 33811417b1cfde8f1749905f2d735623af9214148afJeff Brown mergeDrawableStates(drawableState, CHECKABLE_STATE_SET); 33911417b1cfde8f1749905f2d735623af9214148afJeff Brown } else if (mRemoteActive) { 34011417b1cfde8f1749905f2d735623af9214148afJeff Brown mergeDrawableStates(drawableState, CHECKED_STATE_SET); 34111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 34211417b1cfde8f1749905f2d735623af9214148afJeff Brown return drawableState; 34311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 34411417b1cfde8f1749905f2d735623af9214148afJeff Brown 34511417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 34611417b1cfde8f1749905f2d735623af9214148afJeff Brown protected void drawableStateChanged() { 34711417b1cfde8f1749905f2d735623af9214148afJeff Brown super.drawableStateChanged(); 34811417b1cfde8f1749905f2d735623af9214148afJeff Brown 34911417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mRemoteIndicator != null) { 35011417b1cfde8f1749905f2d735623af9214148afJeff Brown int[] myDrawableState = getDrawableState(); 35111417b1cfde8f1749905f2d735623af9214148afJeff Brown mRemoteIndicator.setState(myDrawableState); 35211417b1cfde8f1749905f2d735623af9214148afJeff Brown invalidate(); 35311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 35411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 35511417b1cfde8f1749905f2d735623af9214148afJeff Brown 35611417b1cfde8f1749905f2d735623af9214148afJeff Brown private void setRemoteIndicatorDrawable(Drawable d) { 35711417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mRemoteIndicator != null) { 35811417b1cfde8f1749905f2d735623af9214148afJeff Brown mRemoteIndicator.setCallback(null); 35911417b1cfde8f1749905f2d735623af9214148afJeff Brown unscheduleDrawable(mRemoteIndicator); 36011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 36111417b1cfde8f1749905f2d735623af9214148afJeff Brown mRemoteIndicator = d; 36211417b1cfde8f1749905f2d735623af9214148afJeff Brown if (d != null) { 36311417b1cfde8f1749905f2d735623af9214148afJeff Brown d.setCallback(this); 36411417b1cfde8f1749905f2d735623af9214148afJeff Brown d.setState(getDrawableState()); 36511417b1cfde8f1749905f2d735623af9214148afJeff Brown d.setVisible(getVisibility() == VISIBLE, false); 36611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 36711417b1cfde8f1749905f2d735623af9214148afJeff Brown 36811417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshDrawableState(); 36911417b1cfde8f1749905f2d735623af9214148afJeff Brown } 37011417b1cfde8f1749905f2d735623af9214148afJeff Brown 37111417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 37211417b1cfde8f1749905f2d735623af9214148afJeff Brown protected boolean verifyDrawable(Drawable who) { 37311417b1cfde8f1749905f2d735623af9214148afJeff Brown return super.verifyDrawable(who) || who == mRemoteIndicator; 37411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 37511417b1cfde8f1749905f2d735623af9214148afJeff Brown 37611417b1cfde8f1749905f2d735623af9214148afJeff Brown //@Override defined in v11 37711417b1cfde8f1749905f2d735623af9214148afJeff Brown public void jumpDrawablesToCurrentState() { 37811417b1cfde8f1749905f2d735623af9214148afJeff Brown // We can't call super to handle the background so we do it ourselves. 37911417b1cfde8f1749905f2d735623af9214148afJeff Brown //super.jumpDrawablesToCurrentState(); 38011417b1cfde8f1749905f2d735623af9214148afJeff Brown if (getBackground() != null) { 38111417b1cfde8f1749905f2d735623af9214148afJeff Brown DrawableCompat.jumpToCurrentState(getBackground()); 38211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 38311417b1cfde8f1749905f2d735623af9214148afJeff Brown 38411417b1cfde8f1749905f2d735623af9214148afJeff Brown // Handle our own remote indicator. 38511417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mRemoteIndicator != null) { 38611417b1cfde8f1749905f2d735623af9214148afJeff Brown DrawableCompat.jumpToCurrentState(mRemoteIndicator); 38711417b1cfde8f1749905f2d735623af9214148afJeff Brown } 38811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 38911417b1cfde8f1749905f2d735623af9214148afJeff Brown 39011417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 39111417b1cfde8f1749905f2d735623af9214148afJeff Brown public void setVisibility(int visibility) { 39211417b1cfde8f1749905f2d735623af9214148afJeff Brown super.setVisibility(visibility); 39311417b1cfde8f1749905f2d735623af9214148afJeff Brown 39411417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mRemoteIndicator != null) { 39511417b1cfde8f1749905f2d735623af9214148afJeff Brown mRemoteIndicator.setVisible(getVisibility() == VISIBLE, false); 39611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 39711417b1cfde8f1749905f2d735623af9214148afJeff Brown } 39811417b1cfde8f1749905f2d735623af9214148afJeff Brown 39911417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 40011417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onAttachedToWindow() { 40111417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onAttachedToWindow(); 40211417b1cfde8f1749905f2d735623af9214148afJeff Brown 40311417b1cfde8f1749905f2d735623af9214148afJeff Brown mAttachedToWindow = true; 4049942d40d0d952b03b583fe66f434676793697aa2Jeff Brown if (!mSelector.isEmpty()) { 4059942d40d0d952b03b583fe66f434676793697aa2Jeff Brown mRouter.addCallback(mSelector, mCallback); 40611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 4079942d40d0d952b03b583fe66f434676793697aa2Jeff Brown refreshRoute(); 40811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 40911417b1cfde8f1749905f2d735623af9214148afJeff Brown 41011417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 41111417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onDetachedFromWindow() { 41211417b1cfde8f1749905f2d735623af9214148afJeff Brown mAttachedToWindow = false; 4139942d40d0d952b03b583fe66f434676793697aa2Jeff Brown if (!mSelector.isEmpty()) { 4149942d40d0d952b03b583fe66f434676793697aa2Jeff Brown mRouter.removeCallback(mCallback); 4159942d40d0d952b03b583fe66f434676793697aa2Jeff Brown } 41611417b1cfde8f1749905f2d735623af9214148afJeff Brown 41711417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onDetachedFromWindow(); 41811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 41911417b1cfde8f1749905f2d735623af9214148afJeff Brown 42011417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 42111417b1cfde8f1749905f2d735623af9214148afJeff Brown protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 42211417b1cfde8f1749905f2d735623af9214148afJeff Brown final int widthSize = MeasureSpec.getSize(widthMeasureSpec); 42311417b1cfde8f1749905f2d735623af9214148afJeff Brown final int heightSize = MeasureSpec.getSize(heightMeasureSpec); 42411417b1cfde8f1749905f2d735623af9214148afJeff Brown final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 42511417b1cfde8f1749905f2d735623af9214148afJeff Brown final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 42611417b1cfde8f1749905f2d735623af9214148afJeff Brown 42711417b1cfde8f1749905f2d735623af9214148afJeff Brown final int minWidth = Math.max(mMinWidth, 42811417b1cfde8f1749905f2d735623af9214148afJeff Brown mRemoteIndicator != null ? mRemoteIndicator.getIntrinsicWidth() : 0); 42911417b1cfde8f1749905f2d735623af9214148afJeff Brown final int minHeight = Math.max(mMinHeight, 43011417b1cfde8f1749905f2d735623af9214148afJeff Brown mRemoteIndicator != null ? mRemoteIndicator.getIntrinsicHeight() : 0); 43111417b1cfde8f1749905f2d735623af9214148afJeff Brown 43211417b1cfde8f1749905f2d735623af9214148afJeff Brown int width; 43311417b1cfde8f1749905f2d735623af9214148afJeff Brown switch (widthMode) { 43411417b1cfde8f1749905f2d735623af9214148afJeff Brown case MeasureSpec.EXACTLY: 43511417b1cfde8f1749905f2d735623af9214148afJeff Brown width = widthSize; 43611417b1cfde8f1749905f2d735623af9214148afJeff Brown break; 43711417b1cfde8f1749905f2d735623af9214148afJeff Brown case MeasureSpec.AT_MOST: 43811417b1cfde8f1749905f2d735623af9214148afJeff Brown width = Math.min(widthSize, minWidth + getPaddingLeft() + getPaddingRight()); 43911417b1cfde8f1749905f2d735623af9214148afJeff Brown break; 44011417b1cfde8f1749905f2d735623af9214148afJeff Brown default: 44111417b1cfde8f1749905f2d735623af9214148afJeff Brown case MeasureSpec.UNSPECIFIED: 44211417b1cfde8f1749905f2d735623af9214148afJeff Brown width = minWidth + getPaddingLeft() + getPaddingRight(); 44311417b1cfde8f1749905f2d735623af9214148afJeff Brown break; 44411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 44511417b1cfde8f1749905f2d735623af9214148afJeff Brown 44611417b1cfde8f1749905f2d735623af9214148afJeff Brown int height; 44711417b1cfde8f1749905f2d735623af9214148afJeff Brown switch (heightMode) { 44811417b1cfde8f1749905f2d735623af9214148afJeff Brown case MeasureSpec.EXACTLY: 44911417b1cfde8f1749905f2d735623af9214148afJeff Brown height = heightSize; 45011417b1cfde8f1749905f2d735623af9214148afJeff Brown break; 45111417b1cfde8f1749905f2d735623af9214148afJeff Brown case MeasureSpec.AT_MOST: 45211417b1cfde8f1749905f2d735623af9214148afJeff Brown height = Math.min(heightSize, minHeight + getPaddingTop() + getPaddingBottom()); 45311417b1cfde8f1749905f2d735623af9214148afJeff Brown break; 45411417b1cfde8f1749905f2d735623af9214148afJeff Brown default: 45511417b1cfde8f1749905f2d735623af9214148afJeff Brown case MeasureSpec.UNSPECIFIED: 45611417b1cfde8f1749905f2d735623af9214148afJeff Brown height = minHeight + getPaddingTop() + getPaddingBottom(); 45711417b1cfde8f1749905f2d735623af9214148afJeff Brown break; 45811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 45911417b1cfde8f1749905f2d735623af9214148afJeff Brown 46011417b1cfde8f1749905f2d735623af9214148afJeff Brown setMeasuredDimension(width, height); 46111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 46211417b1cfde8f1749905f2d735623af9214148afJeff Brown 46311417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 46411417b1cfde8f1749905f2d735623af9214148afJeff Brown protected void onDraw(Canvas canvas) { 46511417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onDraw(canvas); 46611417b1cfde8f1749905f2d735623af9214148afJeff Brown 46711417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mRemoteIndicator != null) { 46811417b1cfde8f1749905f2d735623af9214148afJeff Brown final int left = getPaddingLeft(); 46911417b1cfde8f1749905f2d735623af9214148afJeff Brown final int right = getWidth() - getPaddingRight(); 47011417b1cfde8f1749905f2d735623af9214148afJeff Brown final int top = getPaddingTop(); 47111417b1cfde8f1749905f2d735623af9214148afJeff Brown final int bottom = getHeight() - getPaddingBottom(); 47211417b1cfde8f1749905f2d735623af9214148afJeff Brown 47311417b1cfde8f1749905f2d735623af9214148afJeff Brown final int drawWidth = mRemoteIndicator.getIntrinsicWidth(); 47411417b1cfde8f1749905f2d735623af9214148afJeff Brown final int drawHeight = mRemoteIndicator.getIntrinsicHeight(); 47511417b1cfde8f1749905f2d735623af9214148afJeff Brown final int drawLeft = left + (right - left - drawWidth) / 2; 47611417b1cfde8f1749905f2d735623af9214148afJeff Brown final int drawTop = top + (bottom - top - drawHeight) / 2; 47711417b1cfde8f1749905f2d735623af9214148afJeff Brown 47811417b1cfde8f1749905f2d735623af9214148afJeff Brown mRemoteIndicator.setBounds(drawLeft, drawTop, 47911417b1cfde8f1749905f2d735623af9214148afJeff Brown drawLeft + drawWidth, drawTop + drawHeight); 48011417b1cfde8f1749905f2d735623af9214148afJeff Brown mRemoteIndicator.draw(canvas); 48111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 48211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 48311417b1cfde8f1749905f2d735623af9214148afJeff Brown 48411417b1cfde8f1749905f2d735623af9214148afJeff Brown private void refreshRoute() { 48511417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mAttachedToWindow) { 4869942d40d0d952b03b583fe66f434676793697aa2Jeff Brown final MediaRouter.RouteInfo route = mRouter.getSelectedRoute(); 4879942d40d0d952b03b583fe66f434676793697aa2Jeff Brown final boolean isRemote = !route.isDefault() && route.matchesSelector(mSelector); 4889942d40d0d952b03b583fe66f434676793697aa2Jeff Brown final boolean isConnecting = isRemote && route.isConnecting(); 48911417b1cfde8f1749905f2d735623af9214148afJeff Brown 49011417b1cfde8f1749905f2d735623af9214148afJeff Brown boolean needsRefresh = false; 49111417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mRemoteActive != isRemote) { 49211417b1cfde8f1749905f2d735623af9214148afJeff Brown mRemoteActive = isRemote; 49311417b1cfde8f1749905f2d735623af9214148afJeff Brown needsRefresh = true; 49411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 49511417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mIsConnecting != isConnecting) { 49611417b1cfde8f1749905f2d735623af9214148afJeff Brown mIsConnecting = isConnecting; 49711417b1cfde8f1749905f2d735623af9214148afJeff Brown needsRefresh = true; 49811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 49911417b1cfde8f1749905f2d735623af9214148afJeff Brown 50011417b1cfde8f1749905f2d735623af9214148afJeff Brown if (needsRefresh) { 50111417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshDrawableState(); 50211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 50311417b1cfde8f1749905f2d735623af9214148afJeff Brown 50411417b1cfde8f1749905f2d735623af9214148afJeff Brown setEnabled(mRouter.isRouteAvailable(mSelector, 505d11aa1784335270b8d85e385f2c8be79ee6a586cJeff Brown MediaRouter.AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE)); 50611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 50711417b1cfde8f1749905f2d735623af9214148afJeff Brown } 50811417b1cfde8f1749905f2d735623af9214148afJeff Brown 50911417b1cfde8f1749905f2d735623af9214148afJeff Brown static interface AttachCallback { 51011417b1cfde8f1749905f2d735623af9214148afJeff Brown void onAttachedToWindow(); 51111417b1cfde8f1749905f2d735623af9214148afJeff Brown void onDetachedFromWindow(); 51211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 51311417b1cfde8f1749905f2d735623af9214148afJeff Brown 51411417b1cfde8f1749905f2d735623af9214148afJeff Brown private final class MediaRouterCallback extends MediaRouter.Callback { 51511417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 51611417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) { 51711417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 51811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 51911417b1cfde8f1749905f2d735623af9214148afJeff Brown 52011417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 52111417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info) { 52211417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 52311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 52411417b1cfde8f1749905f2d735623af9214148afJeff Brown 52511417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 52611417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo info) { 52711417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 52811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 52911417b1cfde8f1749905f2d735623af9214148afJeff Brown 53011417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 53111417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) { 53211417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 53311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 53411417b1cfde8f1749905f2d735623af9214148afJeff Brown 53511417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 53611417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo info) { 53711417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 53811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 53911417b1cfde8f1749905f2d735623af9214148afJeff Brown 54011417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 54111417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onProviderAdded(MediaRouter router, MediaRouter.ProviderInfo provider) { 54211417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 54311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 54411417b1cfde8f1749905f2d735623af9214148afJeff Brown 54511417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 54611417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onProviderRemoved(MediaRouter router, MediaRouter.ProviderInfo provider) { 54711417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 54811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 54911417b1cfde8f1749905f2d735623af9214148afJeff Brown 55011417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 55111417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onProviderChanged(MediaRouter router, MediaRouter.ProviderInfo provider) { 55211417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 55311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 55411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 55511417b1cfde8f1749905f2d735623af9214148afJeff Brown} 556