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; 2539dd5560fa1d7ed609dba6945b2579619c9af5b4Sungsoo Limimport android.graphics.drawable.AnimationDrawable; 2611417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.graphics.drawable.Drawable; 27429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbyeimport android.support.annotation.NonNull; 2811417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v4.app.FragmentActivity; 2911417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v4.app.FragmentManager; 3011417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v4.graphics.drawable.DrawableCompat; 3111417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v4.view.GravityCompat; 3211417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouter; 3311417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouteSelector; 3411417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.mediarouter.R; 3511417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.text.TextUtils; 3611417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.util.AttributeSet; 3711417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.util.Log; 3811417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.Gravity; 3911417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.HapticFeedbackConstants; 4011417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.SoundEffectConstants; 4111417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.View; 4211417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.Toast; 4311417b1cfde8f1749905f2d735623af9214148afJeff Brown 4411417b1cfde8f1749905f2d735623af9214148afJeff Brown/** 4511417b1cfde8f1749905f2d735623af9214148afJeff Brown * The media route button allows the user to select routes and to control the 4611417b1cfde8f1749905f2d735623af9214148afJeff Brown * currently selected route. 479942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * <p> 489942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * The application must specify the kinds of routes that the user should be allowed 499942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * to select by specifying a {@link MediaRouteSelector selector} with the 509942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * {@link #setRouteSelector} method. 519942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * </p><p> 529942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * When the default route is selected or when the currently selected route does not 539942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * match the {@link #getRouteSelector() selector}, the button will appear in 549942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * an inactive state indicating that the application is not connected to a 559942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * route of the kind that it wants to use. Clicking on the button opens 569942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * a {@link MediaRouteChooserDialog} to allow the user to select a route. 579942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * If no non-default routes match the selector and it is not possible for an active 589942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * scan to discover any matching routes, then the button is disabled and cannot 599942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * be clicked. 609942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * </p><p> 619942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * When a non-default route is selected that matches the selector, the button will 629942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * appear in an active state indicating that the application is connected 639942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * to a route of the kind that it wants to use. The button may also appear 649942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * in an intermediary connecting state if the route is in the process of connecting 659942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * to the destination but has not yet completed doing so. In either case, clicking 669942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * on the button opens a {@link MediaRouteControllerDialog} to allow the user 679942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * to control or disconnect from the current route. 689942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * </p> 6911417b1cfde8f1749905f2d735623af9214148afJeff Brown * 7011417b1cfde8f1749905f2d735623af9214148afJeff Brown * <h3>Prerequisites</h3> 7111417b1cfde8f1749905f2d735623af9214148afJeff Brown * <p> 7211417b1cfde8f1749905f2d735623af9214148afJeff Brown * To use the media route button, the activity must be a subclass of 7311417b1cfde8f1749905f2d735623af9214148afJeff Brown * {@link FragmentActivity} from the <code>android.support.v4</code> 7411417b1cfde8f1749905f2d735623af9214148afJeff Brown * support library. Refer to support library documentation for details. 7511417b1cfde8f1749905f2d735623af9214148afJeff Brown * </p> 7611417b1cfde8f1749905f2d735623af9214148afJeff Brown * 7711417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see MediaRouteActionProvider 7811417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see #setRouteSelector 7911417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 8011417b1cfde8f1749905f2d735623af9214148afJeff Brownpublic class MediaRouteButton extends View { 8111417b1cfde8f1749905f2d735623af9214148afJeff Brown private static final String TAG = "MediaRouteButton"; 8211417b1cfde8f1749905f2d735623af9214148afJeff Brown 8311417b1cfde8f1749905f2d735623af9214148afJeff Brown private static final String CHOOSER_FRAGMENT_TAG = 8411417b1cfde8f1749905f2d735623af9214148afJeff Brown "android.support.v7.mediarouter:MediaRouteChooserDialogFragment"; 8511417b1cfde8f1749905f2d735623af9214148afJeff Brown private static final String CONTROLLER_FRAGMENT_TAG = 8611417b1cfde8f1749905f2d735623af9214148afJeff Brown "android.support.v7.mediarouter:MediaRouteControllerDialogFragment"; 8711417b1cfde8f1749905f2d735623af9214148afJeff Brown 8811417b1cfde8f1749905f2d735623af9214148afJeff Brown private final MediaRouter mRouter; 8911417b1cfde8f1749905f2d735623af9214148afJeff Brown private final MediaRouterCallback mCallback; 9011417b1cfde8f1749905f2d735623af9214148afJeff Brown 9111417b1cfde8f1749905f2d735623af9214148afJeff Brown private MediaRouteSelector mSelector = MediaRouteSelector.EMPTY; 92eff7719415542ba819054863b0995f07742a7a8aJeff Brown private MediaRouteDialogFactory mDialogFactory = MediaRouteDialogFactory.getDefault(); 9311417b1cfde8f1749905f2d735623af9214148afJeff Brown 9411417b1cfde8f1749905f2d735623af9214148afJeff Brown private boolean mAttachedToWindow; 9511417b1cfde8f1749905f2d735623af9214148afJeff Brown 9611417b1cfde8f1749905f2d735623af9214148afJeff Brown private Drawable mRemoteIndicator; 9711417b1cfde8f1749905f2d735623af9214148afJeff Brown private boolean mRemoteActive; 9811417b1cfde8f1749905f2d735623af9214148afJeff Brown private boolean mCheatSheetEnabled; 9911417b1cfde8f1749905f2d735623af9214148afJeff Brown private boolean mIsConnecting; 10011417b1cfde8f1749905f2d735623af9214148afJeff Brown 10111417b1cfde8f1749905f2d735623af9214148afJeff Brown private int mMinWidth; 10211417b1cfde8f1749905f2d735623af9214148afJeff Brown private int mMinHeight; 10311417b1cfde8f1749905f2d735623af9214148afJeff Brown 10411417b1cfde8f1749905f2d735623af9214148afJeff Brown // The checked state is used when connected to a remote route. 10511417b1cfde8f1749905f2d735623af9214148afJeff Brown private static final int[] CHECKED_STATE_SET = { 10611417b1cfde8f1749905f2d735623af9214148afJeff Brown android.R.attr.state_checked 10711417b1cfde8f1749905f2d735623af9214148afJeff Brown }; 10811417b1cfde8f1749905f2d735623af9214148afJeff Brown 10911417b1cfde8f1749905f2d735623af9214148afJeff Brown // The checkable state is used while connecting to a remote route. 11011417b1cfde8f1749905f2d735623af9214148afJeff Brown private static final int[] CHECKABLE_STATE_SET = { 11111417b1cfde8f1749905f2d735623af9214148afJeff Brown android.R.attr.state_checkable 11211417b1cfde8f1749905f2d735623af9214148afJeff Brown }; 11311417b1cfde8f1749905f2d735623af9214148afJeff Brown 11411417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouteButton(Context context) { 11511417b1cfde8f1749905f2d735623af9214148afJeff Brown this(context, null); 11611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 11711417b1cfde8f1749905f2d735623af9214148afJeff Brown 11811417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouteButton(Context context, AttributeSet attrs) { 11911417b1cfde8f1749905f2d735623af9214148afJeff Brown this(context, attrs, R.attr.mediaRouteButtonStyle); 12011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 12111417b1cfde8f1749905f2d735623af9214148afJeff Brown 12211417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouteButton(Context context, AttributeSet attrs, int defStyleAttr) { 1234448a8e5ed20d230cb838042ff73b6409106cf80Sungsoo Lim super(MediaRouterThemeHelper.createThemedContext(context, defStyleAttr), attrs, 1244448a8e5ed20d230cb838042ff73b6409106cf80Sungsoo Lim defStyleAttr); 12511417b1cfde8f1749905f2d735623af9214148afJeff Brown context = getContext(); 12611417b1cfde8f1749905f2d735623af9214148afJeff Brown 12711417b1cfde8f1749905f2d735623af9214148afJeff Brown mRouter = MediaRouter.getInstance(context); 12811417b1cfde8f1749905f2d735623af9214148afJeff Brown mCallback = new MediaRouterCallback(); 12911417b1cfde8f1749905f2d735623af9214148afJeff Brown 13011417b1cfde8f1749905f2d735623af9214148afJeff Brown TypedArray a = context.obtainStyledAttributes(attrs, 13111417b1cfde8f1749905f2d735623af9214148afJeff Brown R.styleable.MediaRouteButton, defStyleAttr, 0); 13211417b1cfde8f1749905f2d735623af9214148afJeff Brown setRemoteIndicatorDrawable(a.getDrawable( 13311417b1cfde8f1749905f2d735623af9214148afJeff Brown R.styleable.MediaRouteButton_externalRouteEnabledDrawable)); 13411417b1cfde8f1749905f2d735623af9214148afJeff Brown mMinWidth = a.getDimensionPixelSize( 13511417b1cfde8f1749905f2d735623af9214148afJeff Brown R.styleable.MediaRouteButton_android_minWidth, 0); 13611417b1cfde8f1749905f2d735623af9214148afJeff Brown mMinHeight = a.getDimensionPixelSize( 13711417b1cfde8f1749905f2d735623af9214148afJeff Brown R.styleable.MediaRouteButton_android_minHeight, 0); 13811417b1cfde8f1749905f2d735623af9214148afJeff Brown a.recycle(); 13911417b1cfde8f1749905f2d735623af9214148afJeff Brown 140a4667c7f746b153a401442f41ecd94a2487419ffDonghyun Cho updateContentDescription(); 14111417b1cfde8f1749905f2d735623af9214148afJeff Brown setClickable(true); 14211417b1cfde8f1749905f2d735623af9214148afJeff Brown setLongClickable(true); 14311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 14411417b1cfde8f1749905f2d735623af9214148afJeff Brown 14511417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 14611417b1cfde8f1749905f2d735623af9214148afJeff Brown * Gets the media route selector for filtering the routes that the user can 14711417b1cfde8f1749905f2d735623af9214148afJeff Brown * select using the media route chooser dialog. 14811417b1cfde8f1749905f2d735623af9214148afJeff Brown * 14911417b1cfde8f1749905f2d735623af9214148afJeff Brown * @return The selector, never null. 15011417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 151429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbye @NonNull 15211417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouteSelector getRouteSelector() { 15311417b1cfde8f1749905f2d735623af9214148afJeff Brown return mSelector; 15411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 15511417b1cfde8f1749905f2d735623af9214148afJeff Brown 15611417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 15711417b1cfde8f1749905f2d735623af9214148afJeff Brown * Sets the media route selector for filtering the routes that the user can 15811417b1cfde8f1749905f2d735623af9214148afJeff Brown * select using the media route chooser dialog. 15911417b1cfde8f1749905f2d735623af9214148afJeff Brown * 16011417b1cfde8f1749905f2d735623af9214148afJeff Brown * @param selector The selector, must not be null. 16111417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 16211417b1cfde8f1749905f2d735623af9214148afJeff Brown public void setRouteSelector(MediaRouteSelector selector) { 16311417b1cfde8f1749905f2d735623af9214148afJeff Brown if (selector == null) { 16411417b1cfde8f1749905f2d735623af9214148afJeff Brown throw new IllegalArgumentException("selector must not be null"); 16511417b1cfde8f1749905f2d735623af9214148afJeff Brown } 16611417b1cfde8f1749905f2d735623af9214148afJeff Brown 16711417b1cfde8f1749905f2d735623af9214148afJeff Brown if (!mSelector.equals(selector)) { 16811417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mAttachedToWindow) { 1699942d40d0d952b03b583fe66f434676793697aa2Jeff Brown if (!mSelector.isEmpty()) { 1709942d40d0d952b03b583fe66f434676793697aa2Jeff Brown mRouter.removeCallback(mCallback); 1719942d40d0d952b03b583fe66f434676793697aa2Jeff Brown } 1729942d40d0d952b03b583fe66f434676793697aa2Jeff Brown if (!selector.isEmpty()) { 1739942d40d0d952b03b583fe66f434676793697aa2Jeff Brown mRouter.addCallback(selector, mCallback); 1749942d40d0d952b03b583fe66f434676793697aa2Jeff Brown } 17511417b1cfde8f1749905f2d735623af9214148afJeff Brown } 1769942d40d0d952b03b583fe66f434676793697aa2Jeff Brown mSelector = selector; 17711417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 17811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 17911417b1cfde8f1749905f2d735623af9214148afJeff Brown } 18011417b1cfde8f1749905f2d735623af9214148afJeff Brown 18111417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 182eff7719415542ba819054863b0995f07742a7a8aJeff Brown * Gets the media route dialog factory to use when showing the route chooser 183eff7719415542ba819054863b0995f07742a7a8aJeff Brown * or controller dialog. 184eff7719415542ba819054863b0995f07742a7a8aJeff Brown * 185eff7719415542ba819054863b0995f07742a7a8aJeff Brown * @return The dialog factory, never null. 186eff7719415542ba819054863b0995f07742a7a8aJeff Brown */ 187429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbye @NonNull 188eff7719415542ba819054863b0995f07742a7a8aJeff Brown public MediaRouteDialogFactory getDialogFactory() { 189eff7719415542ba819054863b0995f07742a7a8aJeff Brown return mDialogFactory; 190eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 191eff7719415542ba819054863b0995f07742a7a8aJeff Brown 192eff7719415542ba819054863b0995f07742a7a8aJeff Brown /** 193eff7719415542ba819054863b0995f07742a7a8aJeff Brown * Sets the media route dialog factory to use when showing the route chooser 194eff7719415542ba819054863b0995f07742a7a8aJeff Brown * or controller dialog. 195eff7719415542ba819054863b0995f07742a7a8aJeff Brown * 196eff7719415542ba819054863b0995f07742a7a8aJeff Brown * @param factory The dialog factory, must not be null. 197eff7719415542ba819054863b0995f07742a7a8aJeff Brown */ 198429c3b17b88ebd8c4512e9179fd9d48333c0979eTor Norbye public void setDialogFactory(@NonNull MediaRouteDialogFactory factory) { 199eff7719415542ba819054863b0995f07742a7a8aJeff Brown if (factory == null) { 200eff7719415542ba819054863b0995f07742a7a8aJeff Brown throw new IllegalArgumentException("factory must not be null"); 201eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 202eff7719415542ba819054863b0995f07742a7a8aJeff Brown 203eff7719415542ba819054863b0995f07742a7a8aJeff Brown mDialogFactory = factory; 204eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 205eff7719415542ba819054863b0995f07742a7a8aJeff Brown 206eff7719415542ba819054863b0995f07742a7a8aJeff Brown /** 20711417b1cfde8f1749905f2d735623af9214148afJeff Brown * Show the route chooser or controller dialog. 20811417b1cfde8f1749905f2d735623af9214148afJeff Brown * <p> 2099942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * If the default route is selected or if the currently selected route does 2109942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * not match the {@link #getRouteSelector selector}, then shows the route chooser dialog. 2119942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * Otherwise, shows the route controller dialog to offer the user 21211417b1cfde8f1749905f2d735623af9214148afJeff Brown * a choice to disconnect from the route or perform other control actions 21311417b1cfde8f1749905f2d735623af9214148afJeff Brown * such as setting the route's volume. 2149942d40d0d952b03b583fe66f434676793697aa2Jeff Brown * </p><p> 215eff7719415542ba819054863b0995f07742a7a8aJeff Brown * The application can customize the dialogs by calling {@link #setDialogFactory} 216eff7719415542ba819054863b0995f07742a7a8aJeff Brown * to provide a customized dialog factory. 21711417b1cfde8f1749905f2d735623af9214148afJeff Brown * </p> 21811417b1cfde8f1749905f2d735623af9214148afJeff Brown * 21911417b1cfde8f1749905f2d735623af9214148afJeff Brown * @return True if the dialog was actually shown. 22011417b1cfde8f1749905f2d735623af9214148afJeff Brown * 22111417b1cfde8f1749905f2d735623af9214148afJeff Brown * @throws IllegalStateException if the activity is not a subclass of 22211417b1cfde8f1749905f2d735623af9214148afJeff Brown * {@link FragmentActivity}. 22311417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 22411417b1cfde8f1749905f2d735623af9214148afJeff Brown public boolean showDialog() { 22511417b1cfde8f1749905f2d735623af9214148afJeff Brown if (!mAttachedToWindow) { 22611417b1cfde8f1749905f2d735623af9214148afJeff Brown return false; 22711417b1cfde8f1749905f2d735623af9214148afJeff Brown } 22811417b1cfde8f1749905f2d735623af9214148afJeff Brown 22911417b1cfde8f1749905f2d735623af9214148afJeff Brown final FragmentManager fm = getFragmentManager(); 23011417b1cfde8f1749905f2d735623af9214148afJeff Brown if (fm == null) { 23111417b1cfde8f1749905f2d735623af9214148afJeff Brown throw new IllegalStateException("The activity must be a subclass of FragmentActivity"); 23211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 23311417b1cfde8f1749905f2d735623af9214148afJeff Brown 2349942d40d0d952b03b583fe66f434676793697aa2Jeff Brown MediaRouter.RouteInfo route = mRouter.getSelectedRoute(); 235fa19abbe11335366feb6c885f8d75504ab8fe4f9Insun Kang if (route.isDefaultOrBluetooth() || !route.matchesSelector(mSelector)) { 23611417b1cfde8f1749905f2d735623af9214148afJeff Brown if (fm.findFragmentByTag(CHOOSER_FRAGMENT_TAG) != null) { 23711417b1cfde8f1749905f2d735623af9214148afJeff Brown Log.w(TAG, "showDialog(): Route chooser dialog already showing!"); 23811417b1cfde8f1749905f2d735623af9214148afJeff Brown return false; 23911417b1cfde8f1749905f2d735623af9214148afJeff Brown } 240eff7719415542ba819054863b0995f07742a7a8aJeff Brown MediaRouteChooserDialogFragment f = 241eff7719415542ba819054863b0995f07742a7a8aJeff Brown mDialogFactory.onCreateChooserDialogFragment(); 24211417b1cfde8f1749905f2d735623af9214148afJeff Brown f.setRouteSelector(mSelector); 24311417b1cfde8f1749905f2d735623af9214148afJeff Brown f.show(fm, CHOOSER_FRAGMENT_TAG); 24411417b1cfde8f1749905f2d735623af9214148afJeff Brown } else { 24511417b1cfde8f1749905f2d735623af9214148afJeff Brown if (fm.findFragmentByTag(CONTROLLER_FRAGMENT_TAG) != null) { 24611417b1cfde8f1749905f2d735623af9214148afJeff Brown Log.w(TAG, "showDialog(): Route controller dialog already showing!"); 24711417b1cfde8f1749905f2d735623af9214148afJeff Brown return false; 24811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 249eff7719415542ba819054863b0995f07742a7a8aJeff Brown MediaRouteControllerDialogFragment f = 250eff7719415542ba819054863b0995f07742a7a8aJeff Brown mDialogFactory.onCreateControllerDialogFragment(); 25111417b1cfde8f1749905f2d735623af9214148afJeff Brown f.show(fm, CONTROLLER_FRAGMENT_TAG); 25211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 25311417b1cfde8f1749905f2d735623af9214148afJeff Brown return true; 25411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 25511417b1cfde8f1749905f2d735623af9214148afJeff Brown 25611417b1cfde8f1749905f2d735623af9214148afJeff Brown private FragmentManager getFragmentManager() { 25711417b1cfde8f1749905f2d735623af9214148afJeff Brown Activity activity = getActivity(); 25811417b1cfde8f1749905f2d735623af9214148afJeff Brown if (activity instanceof FragmentActivity) { 25911417b1cfde8f1749905f2d735623af9214148afJeff Brown return ((FragmentActivity)activity).getSupportFragmentManager(); 26011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 26111417b1cfde8f1749905f2d735623af9214148afJeff Brown return null; 26211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 26311417b1cfde8f1749905f2d735623af9214148afJeff Brown 26411417b1cfde8f1749905f2d735623af9214148afJeff Brown private Activity getActivity() { 26511417b1cfde8f1749905f2d735623af9214148afJeff Brown // Gross way of unwrapping the Activity so we can get the FragmentManager 26611417b1cfde8f1749905f2d735623af9214148afJeff Brown Context context = getContext(); 26711417b1cfde8f1749905f2d735623af9214148afJeff Brown while (context instanceof ContextWrapper) { 26811417b1cfde8f1749905f2d735623af9214148afJeff Brown if (context instanceof Activity) { 26911417b1cfde8f1749905f2d735623af9214148afJeff Brown return (Activity)context; 27011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 27111417b1cfde8f1749905f2d735623af9214148afJeff Brown context = ((ContextWrapper)context).getBaseContext(); 27211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 27311417b1cfde8f1749905f2d735623af9214148afJeff Brown return null; 27411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 27511417b1cfde8f1749905f2d735623af9214148afJeff Brown 27611417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 27711417b1cfde8f1749905f2d735623af9214148afJeff Brown * Sets whether to enable showing a toast with the content descriptor of the 27811417b1cfde8f1749905f2d735623af9214148afJeff Brown * button when the button is long pressed. 27911417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 28011417b1cfde8f1749905f2d735623af9214148afJeff Brown void setCheatSheetEnabled(boolean enable) { 28111417b1cfde8f1749905f2d735623af9214148afJeff Brown mCheatSheetEnabled = enable; 28211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 28311417b1cfde8f1749905f2d735623af9214148afJeff Brown 28411417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 28511417b1cfde8f1749905f2d735623af9214148afJeff Brown public boolean performClick() { 28611417b1cfde8f1749905f2d735623af9214148afJeff Brown // Send the appropriate accessibility events and call listeners 28711417b1cfde8f1749905f2d735623af9214148afJeff Brown boolean handled = super.performClick(); 28811417b1cfde8f1749905f2d735623af9214148afJeff Brown if (!handled) { 28911417b1cfde8f1749905f2d735623af9214148afJeff Brown playSoundEffect(SoundEffectConstants.CLICK); 29011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 29111417b1cfde8f1749905f2d735623af9214148afJeff Brown return showDialog() || handled; 29211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 29311417b1cfde8f1749905f2d735623af9214148afJeff Brown 29411417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 29511417b1cfde8f1749905f2d735623af9214148afJeff Brown public boolean performLongClick() { 29611417b1cfde8f1749905f2d735623af9214148afJeff Brown if (super.performLongClick()) { 29711417b1cfde8f1749905f2d735623af9214148afJeff Brown return true; 29811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 29911417b1cfde8f1749905f2d735623af9214148afJeff Brown 30011417b1cfde8f1749905f2d735623af9214148afJeff Brown if (!mCheatSheetEnabled) { 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 315a4667c7f746b153a401442f41ecd94a2487419ffDonghyun Cho Toast cheatSheet = Toast.makeText(context, R.string.mr_button_content_description, 316a4667c7f746b153a401442f41ecd94a2487419ffDonghyun Cho Toast.LENGTH_SHORT); 31711417b1cfde8f1749905f2d735623af9214148afJeff Brown if (midy < displayFrame.height()) { 31811417b1cfde8f1749905f2d735623af9214148afJeff Brown // Show along the top; follow action buttons 31911417b1cfde8f1749905f2d735623af9214148afJeff Brown cheatSheet.setGravity(Gravity.TOP | GravityCompat.END, 32011417b1cfde8f1749905f2d735623af9214148afJeff Brown screenWidth - screenPos[0] - width / 2, height); 32111417b1cfde8f1749905f2d735623af9214148afJeff Brown } else { 32211417b1cfde8f1749905f2d735623af9214148afJeff Brown // Show along the bottom center 32311417b1cfde8f1749905f2d735623af9214148afJeff Brown cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height); 32411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 32511417b1cfde8f1749905f2d735623af9214148afJeff Brown cheatSheet.show(); 32611417b1cfde8f1749905f2d735623af9214148afJeff Brown performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); 32711417b1cfde8f1749905f2d735623af9214148afJeff Brown return true; 32811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 32911417b1cfde8f1749905f2d735623af9214148afJeff Brown 33011417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 33111417b1cfde8f1749905f2d735623af9214148afJeff Brown protected int[] onCreateDrawableState(int extraSpace) { 33211417b1cfde8f1749905f2d735623af9214148afJeff Brown final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 33311417b1cfde8f1749905f2d735623af9214148afJeff Brown 33411417b1cfde8f1749905f2d735623af9214148afJeff Brown // Technically we should be handling this more completely, but these 33511417b1cfde8f1749905f2d735623af9214148afJeff Brown // are implementation details here. Checkable is used to express the connecting 33611417b1cfde8f1749905f2d735623af9214148afJeff Brown // drawable state and it's mutually exclusive with check for the purposes 33711417b1cfde8f1749905f2d735623af9214148afJeff Brown // of state selection here. 33811417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mIsConnecting) { 33911417b1cfde8f1749905f2d735623af9214148afJeff Brown mergeDrawableStates(drawableState, CHECKABLE_STATE_SET); 34011417b1cfde8f1749905f2d735623af9214148afJeff Brown } else if (mRemoteActive) { 34111417b1cfde8f1749905f2d735623af9214148afJeff Brown mergeDrawableStates(drawableState, CHECKED_STATE_SET); 34211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 34311417b1cfde8f1749905f2d735623af9214148afJeff Brown return drawableState; 34411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 34511417b1cfde8f1749905f2d735623af9214148afJeff Brown 34611417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 34711417b1cfde8f1749905f2d735623af9214148afJeff Brown protected void drawableStateChanged() { 34811417b1cfde8f1749905f2d735623af9214148afJeff Brown super.drawableStateChanged(); 34911417b1cfde8f1749905f2d735623af9214148afJeff Brown 35011417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mRemoteIndicator != null) { 35111417b1cfde8f1749905f2d735623af9214148afJeff Brown int[] myDrawableState = getDrawableState(); 35211417b1cfde8f1749905f2d735623af9214148afJeff Brown mRemoteIndicator.setState(myDrawableState); 35311417b1cfde8f1749905f2d735623af9214148afJeff Brown invalidate(); 35411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 35511417b1cfde8f1749905f2d735623af9214148afJeff Brown } 35611417b1cfde8f1749905f2d735623af9214148afJeff Brown 357fa0c1799716878268ad8705818bb2cbe47338c9dP.Y. Laligand /** 358fa0c1799716878268ad8705818bb2cbe47338c9dP.Y. Laligand * Sets a drawable to use as the remote route indicator. 359fa0c1799716878268ad8705818bb2cbe47338c9dP.Y. Laligand */ 360fa0c1799716878268ad8705818bb2cbe47338c9dP.Y. Laligand public void setRemoteIndicatorDrawable(Drawable d) { 36111417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mRemoteIndicator != null) { 36211417b1cfde8f1749905f2d735623af9214148afJeff Brown mRemoteIndicator.setCallback(null); 36311417b1cfde8f1749905f2d735623af9214148afJeff Brown unscheduleDrawable(mRemoteIndicator); 36411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 36511417b1cfde8f1749905f2d735623af9214148afJeff Brown mRemoteIndicator = d; 36611417b1cfde8f1749905f2d735623af9214148afJeff Brown if (d != null) { 36711417b1cfde8f1749905f2d735623af9214148afJeff Brown d.setCallback(this); 36811417b1cfde8f1749905f2d735623af9214148afJeff Brown d.setState(getDrawableState()); 36911417b1cfde8f1749905f2d735623af9214148afJeff Brown d.setVisible(getVisibility() == VISIBLE, false); 37011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 37111417b1cfde8f1749905f2d735623af9214148afJeff Brown 37211417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshDrawableState(); 37311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 37411417b1cfde8f1749905f2d735623af9214148afJeff Brown 37511417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 37611417b1cfde8f1749905f2d735623af9214148afJeff Brown protected boolean verifyDrawable(Drawable who) { 37711417b1cfde8f1749905f2d735623af9214148afJeff Brown return super.verifyDrawable(who) || who == mRemoteIndicator; 37811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 37911417b1cfde8f1749905f2d735623af9214148afJeff Brown 38011417b1cfde8f1749905f2d735623af9214148afJeff Brown //@Override defined in v11 38111417b1cfde8f1749905f2d735623af9214148afJeff Brown public void jumpDrawablesToCurrentState() { 38211417b1cfde8f1749905f2d735623af9214148afJeff Brown // We can't call super to handle the background so we do it ourselves. 38311417b1cfde8f1749905f2d735623af9214148afJeff Brown //super.jumpDrawablesToCurrentState(); 38411417b1cfde8f1749905f2d735623af9214148afJeff Brown if (getBackground() != null) { 38511417b1cfde8f1749905f2d735623af9214148afJeff Brown DrawableCompat.jumpToCurrentState(getBackground()); 38611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 38711417b1cfde8f1749905f2d735623af9214148afJeff Brown 38811417b1cfde8f1749905f2d735623af9214148afJeff Brown // Handle our own remote indicator. 38911417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mRemoteIndicator != null) { 39011417b1cfde8f1749905f2d735623af9214148afJeff Brown DrawableCompat.jumpToCurrentState(mRemoteIndicator); 39111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 39211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 39311417b1cfde8f1749905f2d735623af9214148afJeff Brown 39411417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 39511417b1cfde8f1749905f2d735623af9214148afJeff Brown public void setVisibility(int visibility) { 39611417b1cfde8f1749905f2d735623af9214148afJeff Brown super.setVisibility(visibility); 39711417b1cfde8f1749905f2d735623af9214148afJeff Brown 39811417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mRemoteIndicator != null) { 39911417b1cfde8f1749905f2d735623af9214148afJeff Brown mRemoteIndicator.setVisible(getVisibility() == VISIBLE, false); 40011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 40111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 40211417b1cfde8f1749905f2d735623af9214148afJeff Brown 40311417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 40411417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onAttachedToWindow() { 40511417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onAttachedToWindow(); 40611417b1cfde8f1749905f2d735623af9214148afJeff Brown 40711417b1cfde8f1749905f2d735623af9214148afJeff Brown mAttachedToWindow = true; 4089942d40d0d952b03b583fe66f434676793697aa2Jeff Brown if (!mSelector.isEmpty()) { 4099942d40d0d952b03b583fe66f434676793697aa2Jeff Brown mRouter.addCallback(mSelector, mCallback); 41011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 4119942d40d0d952b03b583fe66f434676793697aa2Jeff Brown refreshRoute(); 41211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 41311417b1cfde8f1749905f2d735623af9214148afJeff Brown 41411417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 41511417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onDetachedFromWindow() { 41611417b1cfde8f1749905f2d735623af9214148afJeff Brown mAttachedToWindow = false; 4179942d40d0d952b03b583fe66f434676793697aa2Jeff Brown if (!mSelector.isEmpty()) { 4189942d40d0d952b03b583fe66f434676793697aa2Jeff Brown mRouter.removeCallback(mCallback); 4199942d40d0d952b03b583fe66f434676793697aa2Jeff Brown } 42011417b1cfde8f1749905f2d735623af9214148afJeff Brown 42111417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onDetachedFromWindow(); 42211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 42311417b1cfde8f1749905f2d735623af9214148afJeff Brown 42411417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 42511417b1cfde8f1749905f2d735623af9214148afJeff Brown protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 42611417b1cfde8f1749905f2d735623af9214148afJeff Brown final int widthSize = MeasureSpec.getSize(widthMeasureSpec); 42711417b1cfde8f1749905f2d735623af9214148afJeff Brown final int heightSize = MeasureSpec.getSize(heightMeasureSpec); 42811417b1cfde8f1749905f2d735623af9214148afJeff Brown final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 42911417b1cfde8f1749905f2d735623af9214148afJeff Brown final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 43011417b1cfde8f1749905f2d735623af9214148afJeff Brown 4315a7cd823706ba63d809545516bdbbc6e8ac8b998Dongwon Kang final int width = Math.max(mMinWidth, mRemoteIndicator != null ? 4325a7cd823706ba63d809545516bdbbc6e8ac8b998Dongwon Kang mRemoteIndicator.getIntrinsicWidth() + getPaddingLeft() + getPaddingRight() : 0); 4335a7cd823706ba63d809545516bdbbc6e8ac8b998Dongwon Kang final int height = Math.max(mMinHeight, mRemoteIndicator != null ? 4345a7cd823706ba63d809545516bdbbc6e8ac8b998Dongwon Kang mRemoteIndicator.getIntrinsicHeight() + getPaddingTop() + getPaddingBottom() : 0); 43511417b1cfde8f1749905f2d735623af9214148afJeff Brown 4365a7cd823706ba63d809545516bdbbc6e8ac8b998Dongwon Kang int measuredWidth; 43711417b1cfde8f1749905f2d735623af9214148afJeff Brown switch (widthMode) { 43811417b1cfde8f1749905f2d735623af9214148afJeff Brown case MeasureSpec.EXACTLY: 4395a7cd823706ba63d809545516bdbbc6e8ac8b998Dongwon Kang measuredWidth = widthSize; 44011417b1cfde8f1749905f2d735623af9214148afJeff Brown break; 44111417b1cfde8f1749905f2d735623af9214148afJeff Brown case MeasureSpec.AT_MOST: 4425a7cd823706ba63d809545516bdbbc6e8ac8b998Dongwon Kang measuredWidth = Math.min(widthSize, width); 44311417b1cfde8f1749905f2d735623af9214148afJeff Brown break; 44411417b1cfde8f1749905f2d735623af9214148afJeff Brown default: 44511417b1cfde8f1749905f2d735623af9214148afJeff Brown case MeasureSpec.UNSPECIFIED: 4465a7cd823706ba63d809545516bdbbc6e8ac8b998Dongwon Kang measuredWidth = width; 44711417b1cfde8f1749905f2d735623af9214148afJeff Brown break; 44811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 44911417b1cfde8f1749905f2d735623af9214148afJeff Brown 4505a7cd823706ba63d809545516bdbbc6e8ac8b998Dongwon Kang int measuredHeight; 45111417b1cfde8f1749905f2d735623af9214148afJeff Brown switch (heightMode) { 45211417b1cfde8f1749905f2d735623af9214148afJeff Brown case MeasureSpec.EXACTLY: 4535a7cd823706ba63d809545516bdbbc6e8ac8b998Dongwon Kang measuredHeight = heightSize; 45411417b1cfde8f1749905f2d735623af9214148afJeff Brown break; 45511417b1cfde8f1749905f2d735623af9214148afJeff Brown case MeasureSpec.AT_MOST: 4565a7cd823706ba63d809545516bdbbc6e8ac8b998Dongwon Kang measuredHeight = Math.min(heightSize, height); 45711417b1cfde8f1749905f2d735623af9214148afJeff Brown break; 45811417b1cfde8f1749905f2d735623af9214148afJeff Brown default: 45911417b1cfde8f1749905f2d735623af9214148afJeff Brown case MeasureSpec.UNSPECIFIED: 4605a7cd823706ba63d809545516bdbbc6e8ac8b998Dongwon Kang measuredHeight = height; 46111417b1cfde8f1749905f2d735623af9214148afJeff Brown break; 46211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 46311417b1cfde8f1749905f2d735623af9214148afJeff Brown 4645a7cd823706ba63d809545516bdbbc6e8ac8b998Dongwon Kang setMeasuredDimension(measuredWidth, measuredHeight); 46511417b1cfde8f1749905f2d735623af9214148afJeff Brown } 46611417b1cfde8f1749905f2d735623af9214148afJeff Brown 46711417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 46811417b1cfde8f1749905f2d735623af9214148afJeff Brown protected void onDraw(Canvas canvas) { 46911417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onDraw(canvas); 47011417b1cfde8f1749905f2d735623af9214148afJeff Brown 47111417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mRemoteIndicator != null) { 47211417b1cfde8f1749905f2d735623af9214148afJeff Brown final int left = getPaddingLeft(); 47311417b1cfde8f1749905f2d735623af9214148afJeff Brown final int right = getWidth() - getPaddingRight(); 47411417b1cfde8f1749905f2d735623af9214148afJeff Brown final int top = getPaddingTop(); 47511417b1cfde8f1749905f2d735623af9214148afJeff Brown final int bottom = getHeight() - getPaddingBottom(); 47611417b1cfde8f1749905f2d735623af9214148afJeff Brown 47711417b1cfde8f1749905f2d735623af9214148afJeff Brown final int drawWidth = mRemoteIndicator.getIntrinsicWidth(); 47811417b1cfde8f1749905f2d735623af9214148afJeff Brown final int drawHeight = mRemoteIndicator.getIntrinsicHeight(); 47911417b1cfde8f1749905f2d735623af9214148afJeff Brown final int drawLeft = left + (right - left - drawWidth) / 2; 48011417b1cfde8f1749905f2d735623af9214148afJeff Brown final int drawTop = top + (bottom - top - drawHeight) / 2; 48111417b1cfde8f1749905f2d735623af9214148afJeff Brown 48211417b1cfde8f1749905f2d735623af9214148afJeff Brown mRemoteIndicator.setBounds(drawLeft, drawTop, 48311417b1cfde8f1749905f2d735623af9214148afJeff Brown drawLeft + drawWidth, drawTop + drawHeight); 48411417b1cfde8f1749905f2d735623af9214148afJeff Brown mRemoteIndicator.draw(canvas); 48511417b1cfde8f1749905f2d735623af9214148afJeff Brown } 48611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 48711417b1cfde8f1749905f2d735623af9214148afJeff Brown 488e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas void refreshRoute() { 48911417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mAttachedToWindow) { 4909942d40d0d952b03b583fe66f434676793697aa2Jeff Brown final MediaRouter.RouteInfo route = mRouter.getSelectedRoute(); 491fa19abbe11335366feb6c885f8d75504ab8fe4f9Insun Kang final boolean isRemote = !route.isDefaultOrBluetooth() 492fa19abbe11335366feb6c885f8d75504ab8fe4f9Insun Kang && route.matchesSelector(mSelector); 4939942d40d0d952b03b583fe66f434676793697aa2Jeff Brown final boolean isConnecting = isRemote && route.isConnecting(); 49411417b1cfde8f1749905f2d735623af9214148afJeff Brown 49511417b1cfde8f1749905f2d735623af9214148afJeff Brown boolean needsRefresh = false; 49611417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mRemoteActive != isRemote) { 49711417b1cfde8f1749905f2d735623af9214148afJeff Brown mRemoteActive = isRemote; 49811417b1cfde8f1749905f2d735623af9214148afJeff Brown needsRefresh = true; 49911417b1cfde8f1749905f2d735623af9214148afJeff Brown } 50011417b1cfde8f1749905f2d735623af9214148afJeff Brown if (mIsConnecting != isConnecting) { 50111417b1cfde8f1749905f2d735623af9214148afJeff Brown mIsConnecting = isConnecting; 50211417b1cfde8f1749905f2d735623af9214148afJeff Brown needsRefresh = true; 50311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 50411417b1cfde8f1749905f2d735623af9214148afJeff Brown 50511417b1cfde8f1749905f2d735623af9214148afJeff Brown if (needsRefresh) { 506a4667c7f746b153a401442f41ecd94a2487419ffDonghyun Cho updateContentDescription(); 50711417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshDrawableState(); 5086dc709cd8ea483663e1a9d6730e081eb82bdb02aSungsoo Lim if (mRemoteIndicator.getCurrent() instanceof AnimationDrawable) { 50939dd5560fa1d7ed609dba6945b2579619c9af5b4Sungsoo Lim AnimationDrawable curDrawable = 51039dd5560fa1d7ed609dba6945b2579619c9af5b4Sungsoo Lim (AnimationDrawable) mRemoteIndicator.getCurrent(); 51139dd5560fa1d7ed609dba6945b2579619c9af5b4Sungsoo Lim if (!curDrawable.isRunning()) { 51239dd5560fa1d7ed609dba6945b2579619c9af5b4Sungsoo Lim curDrawable.start(); 51339dd5560fa1d7ed609dba6945b2579619c9af5b4Sungsoo Lim } 51439dd5560fa1d7ed609dba6945b2579619c9af5b4Sungsoo Lim } 51511417b1cfde8f1749905f2d735623af9214148afJeff Brown } 516dffce799b08cbea89247cffc19c8f91bc592ec81Sungsoo Lim 517dffce799b08cbea89247cffc19c8f91bc592ec81Sungsoo Lim setEnabled(mRouter.isRouteAvailable(mSelector, 518dffce799b08cbea89247cffc19c8f91bc592ec81Sungsoo Lim MediaRouter.AVAILABILITY_FLAG_IGNORE_DEFAULT_ROUTE)); 51911417b1cfde8f1749905f2d735623af9214148afJeff Brown } 52011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 52111417b1cfde8f1749905f2d735623af9214148afJeff Brown 522a4667c7f746b153a401442f41ecd94a2487419ffDonghyun Cho private void updateContentDescription() { 523a4667c7f746b153a401442f41ecd94a2487419ffDonghyun Cho int resId; 524a4667c7f746b153a401442f41ecd94a2487419ffDonghyun Cho if (mIsConnecting) { 525a4667c7f746b153a401442f41ecd94a2487419ffDonghyun Cho resId = R.string.mr_cast_button_connecting; 526a4667c7f746b153a401442f41ecd94a2487419ffDonghyun Cho } else if (mRemoteActive) { 527a4667c7f746b153a401442f41ecd94a2487419ffDonghyun Cho resId = R.string.mr_cast_button_connected; 528a4667c7f746b153a401442f41ecd94a2487419ffDonghyun Cho } else { 529a4667c7f746b153a401442f41ecd94a2487419ffDonghyun Cho resId = R.string.mr_cast_button_disconnected; 530a4667c7f746b153a401442f41ecd94a2487419ffDonghyun Cho } 531a4667c7f746b153a401442f41ecd94a2487419ffDonghyun Cho setContentDescription(getContext().getString(resId)); 532a4667c7f746b153a401442f41ecd94a2487419ffDonghyun Cho } 533a4667c7f746b153a401442f41ecd94a2487419ffDonghyun Cho 53411417b1cfde8f1749905f2d735623af9214148afJeff Brown private final class MediaRouterCallback extends MediaRouter.Callback { 535e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas MediaRouterCallback() { 536e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas } 537e2c6a94b6e4aab502f9b88dd3ff664bd90b25839Aurimas Liutikas 53811417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 53911417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteAdded(MediaRouter router, MediaRouter.RouteInfo info) { 54011417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 54111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 54211417b1cfde8f1749905f2d735623af9214148afJeff Brown 54311417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 54411417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteRemoved(MediaRouter router, MediaRouter.RouteInfo info) { 54511417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 54611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 54711417b1cfde8f1749905f2d735623af9214148afJeff Brown 54811417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 54911417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo info) { 55011417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 55111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 55211417b1cfde8f1749905f2d735623af9214148afJeff Brown 55311417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 55411417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo info) { 55511417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 55611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 55711417b1cfde8f1749905f2d735623af9214148afJeff Brown 55811417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 55911417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo info) { 56011417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 56111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 56211417b1cfde8f1749905f2d735623af9214148afJeff Brown 56311417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 56411417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onProviderAdded(MediaRouter router, MediaRouter.ProviderInfo provider) { 56511417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 56611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 56711417b1cfde8f1749905f2d735623af9214148afJeff Brown 56811417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 56911417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onProviderRemoved(MediaRouter router, MediaRouter.ProviderInfo provider) { 57011417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 57111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 57211417b1cfde8f1749905f2d735623af9214148afJeff Brown 57311417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 57411417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onProviderChanged(MediaRouter router, MediaRouter.ProviderInfo provider) { 57511417b1cfde8f1749905f2d735623af9214148afJeff Brown refreshRoute(); 57611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 57711417b1cfde8f1749905f2d735623af9214148afJeff Brown } 57811417b1cfde8f1749905f2d735623af9214148afJeff Brown} 579