MediaRouteButton.java revision 2ee6a2a83262d05a566bd713d238e89edfd33a29
1690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell/*
2690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * Copyright (C) 2012 The Android Open Source Project
3690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell *
4690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * Licensed under the Apache License, Version 2.0 (the "License");
5690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * you may not use this file except in compliance with the License.
6690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * You may obtain a copy of the License at
7690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell *
8690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell *      http://www.apache.org/licenses/LICENSE-2.0
9690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell *
10690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * Unless required by applicable law or agreed to in writing, software
11690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * distributed under the License is distributed on an "AS IS" BASIS,
12690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * See the License for the specific language governing permissions and
14690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell * limitations under the License.
15690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell */
16690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
17690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellpackage android.app;
18690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
19690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport com.android.internal.R;
2070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport com.android.internal.app.MediaRouteChooserDialogFragment;
21690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
22690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.content.Context;
2370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powellimport android.content.ContextWrapper;
24690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.content.res.TypedArray;
25690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.graphics.Canvas;
26e4681878702edaf0833294b3f1ce835705d3ad04Adam Powellimport android.graphics.Rect;
27690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.graphics.drawable.Drawable;
28690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.media.MediaRouter;
29f7e0a328c939fa61792d4b685e8f9047a3a0ad90Adam Powellimport android.media.MediaRouter.RouteGroup;
30690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.media.MediaRouter.RouteInfo;
31e4681878702edaf0833294b3f1ce835705d3ad04Adam Powellimport android.text.TextUtils;
32690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.util.AttributeSet;
33690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.util.Log;
34e4681878702edaf0833294b3f1ce835705d3ad04Adam Powellimport android.view.Gravity;
35e4681878702edaf0833294b3f1ce835705d3ad04Adam Powellimport android.view.HapticFeedbackConstants;
36690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.view.SoundEffectConstants;
37690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.view.View;
38e4681878702edaf0833294b3f1ce835705d3ad04Adam Powellimport android.widget.Toast;
39690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
40690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellpublic class MediaRouteButton extends View {
41690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    private static final String TAG = "MediaRouteButton";
42690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
43690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    private MediaRouter mRouter;
44690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    private final MediaRouteCallback mRouterCallback = new MediaRouteCallback();
45690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    private int mRouteTypes;
46690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
47101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich    private boolean mAttachedToWindow;
48101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich
49690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    private Drawable mRemoteIndicator;
50690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    private boolean mRemoteActive;
51690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    private boolean mToggleMode;
52e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell    private boolean mCheatSheetEnabled;
532ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell    private boolean mIsConnecting;
54690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
55690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    private int mMinWidth;
56690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    private int mMinHeight;
57690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
58b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell    private OnClickListener mExtendedSettingsClickListener;
5970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell    private MediaRouteChooserDialogFragment mDialogFragment;
60b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell
612ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell    private static final int[] CHECKED_STATE_SET = {
622ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        R.attr.state_checked
632ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell    };
642ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell
65690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    private static final int[] ACTIVATED_STATE_SET = {
66690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        R.attr.state_activated
67690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    };
68690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
69690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    public MediaRouteButton(Context context) {
70690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        this(context, null);
71690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
72690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
73690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    public MediaRouteButton(Context context, AttributeSet attrs) {
7474d762a3ee7dd66fe9ce44f3232159811af8d5d8Adam Powell        this(context, attrs, com.android.internal.R.attr.mediaRouteButtonStyle);
75690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
76690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
77690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    public MediaRouteButton(Context context, AttributeSet attrs, int defStyleAttr) {
78690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        super(context, attrs, defStyleAttr);
79690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
80b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn        mRouter = (MediaRouter)context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
81690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
82690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        TypedArray a = context.obtainStyledAttributes(attrs,
83690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                com.android.internal.R.styleable.MediaRouteButton, defStyleAttr, 0);
84690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        setRemoteIndicatorDrawable(a.getDrawable(
85690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                com.android.internal.R.styleable.MediaRouteButton_externalRouteEnabledDrawable));
86690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        mMinWidth = a.getDimensionPixelSize(
87690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                com.android.internal.R.styleable.MediaRouteButton_minWidth, 0);
88690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        mMinHeight = a.getDimensionPixelSize(
89690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                com.android.internal.R.styleable.MediaRouteButton_minHeight, 0);
90849df0b5a7a5ef72610d687a8b1c2f0a23f873abAdam Powell        final int routeTypes = a.getInteger(
91849df0b5a7a5ef72610d687a8b1c2f0a23f873abAdam Powell                com.android.internal.R.styleable.MediaRouteButton_mediaRouteTypes,
92849df0b5a7a5ef72610d687a8b1c2f0a23f873abAdam Powell                MediaRouter.ROUTE_TYPE_LIVE_AUDIO);
93690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        a.recycle();
94690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
95690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        setClickable(true);
96e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        setLongClickable(true);
97849df0b5a7a5ef72610d687a8b1c2f0a23f873abAdam Powell
98849df0b5a7a5ef72610d687a8b1c2f0a23f873abAdam Powell        setRouteTypes(routeTypes);
99690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
100690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
101690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    private void setRemoteIndicatorDrawable(Drawable d) {
102690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        if (mRemoteIndicator != null) {
103690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            mRemoteIndicator.setCallback(null);
104690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            unscheduleDrawable(mRemoteIndicator);
105690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
106690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        mRemoteIndicator = d;
107690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        if (d != null) {
108690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            d.setCallback(this);
109690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            d.setState(getDrawableState());
110690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            d.setVisible(getVisibility() == VISIBLE, false);
111690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
112690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
113690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        refreshDrawableState();
114690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
115690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
116690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    @Override
117690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    public boolean performClick() {
118690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        // Send the appropriate accessibility events and call listeners
119690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        boolean handled = super.performClick();
120690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        if (!handled) {
121690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            playSoundEffect(SoundEffectConstants.CLICK);
122690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
123690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
124690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        if (mToggleMode) {
125690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            if (mRemoteActive) {
1260d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell                mRouter.selectRouteInt(mRouteTypes, mRouter.getSystemAudioRoute());
127690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            } else {
128690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                final int N = mRouter.getRouteCount();
129690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                for (int i = 0; i < N; i++) {
130690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                    final RouteInfo route = mRouter.getRouteAt(i);
131690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                    if ((route.getSupportedTypes() & mRouteTypes) != 0 &&
132690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                            route != mRouter.getSystemAudioRoute()) {
133eba1b70d7a66fa8299307895ec6d6d6495b387f0Adam Powell                        mRouter.selectRouteInt(mRouteTypes, route);
134690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                    }
135690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                }
136690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            }
137690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        } else {
13870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell            showDialog();
139690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
140690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
141690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        return handled;
142690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
143690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
144e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell    void setCheatSheetEnabled(boolean enable) {
145e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        mCheatSheetEnabled = enable;
146e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell    }
147e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell
148e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell    @Override
149e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell    public boolean performLongClick() {
150e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        if (super.performLongClick()) {
151e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell            return true;
152e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        }
153e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell
154e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        if (!mCheatSheetEnabled) {
155e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell            return false;
156e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        }
157e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell
158e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        final CharSequence contentDesc = getContentDescription();
159e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        if (TextUtils.isEmpty(contentDesc)) {
160e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell            // Don't show the cheat sheet if we have no description
161e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell            return false;
162e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        }
163e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell
164e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        final int[] screenPos = new int[2];
165e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        final Rect displayFrame = new Rect();
166e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        getLocationOnScreen(screenPos);
167e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        getWindowVisibleDisplayFrame(displayFrame);
168e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell
169e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        final Context context = getContext();
170e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        final int width = getWidth();
171e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        final int height = getHeight();
172e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        final int midy = screenPos[1] + height / 2;
173e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        final int screenWidth = context.getResources().getDisplayMetrics().widthPixels;
174e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell
175e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        Toast cheatSheet = Toast.makeText(context, contentDesc, Toast.LENGTH_SHORT);
176e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        if (midy < displayFrame.height()) {
177e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell            // Show along the top; follow action buttons
178e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell            cheatSheet.setGravity(Gravity.TOP | Gravity.END,
179e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell                    screenWidth - screenPos[0] - width / 2, height);
180e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        } else {
181e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell            // Show along the bottom center
182e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell            cheatSheet.setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL, 0, height);
183e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        }
184e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        cheatSheet.show();
185e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
186e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell
187e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell        return true;
188e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell    }
189e4681878702edaf0833294b3f1ce835705d3ad04Adam Powell
190690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    public void setRouteTypes(int types) {
191690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        if (types == mRouteTypes) {
192690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            // Already registered; nothing to do.
193690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            return;
194690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
195101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich
196101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich        if (mAttachedToWindow && mRouteTypes != 0) {
197690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            mRouter.removeCallback(mRouterCallback);
198690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
199101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich
200690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        mRouteTypes = types;
201101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich
202101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich        if (mAttachedToWindow) {
203101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich            updateRouteInfo();
204101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich            mRouter.addCallback(types, mRouterCallback);
205101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich        }
206101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich    }
207101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich
208101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich    private void updateRouteInfo() {
209690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        updateRemoteIndicator();
210690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        updateRouteCount();
211690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
212690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
213690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    public int getRouteTypes() {
214690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        return mRouteTypes;
215690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
216690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
217690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    void updateRemoteIndicator() {
2182ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        final RouteInfo selected = mRouter.getSelectedRoute(mRouteTypes);
2192ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        final boolean isRemote = selected != mRouter.getSystemAudioRoute();
2202ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        final boolean isConnecting = selected.getStatusCode() == RouteInfo.STATUS_CONNECTING;
2212ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell
2222ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        boolean needsRefresh = false;
223690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        if (mRemoteActive != isRemote) {
224690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            mRemoteActive = isRemote;
2252ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell            needsRefresh = true;
2262ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        }
2272ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        if (mIsConnecting != isConnecting) {
2282ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell            mIsConnecting = isConnecting;
2292ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell            needsRefresh = true;
2302ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        }
2312ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell
2322ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        if (needsRefresh) {
233690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            refreshDrawableState();
234690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
235690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
236690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
237690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    void updateRouteCount() {
238690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        final int N = mRouter.getRouteCount();
239690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        int count = 0;
240705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell        boolean hasVideoRoutes = false;
241690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        for (int i = 0; i < N; i++) {
242f7e0a328c939fa61792d4b685e8f9047a3a0ad90Adam Powell            final RouteInfo route = mRouter.getRouteAt(i);
243705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell            final int routeTypes = route.getSupportedTypes();
244705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell            if ((routeTypes & mRouteTypes) != 0) {
245f7e0a328c939fa61792d4b685e8f9047a3a0ad90Adam Powell                if (route instanceof RouteGroup) {
246f7e0a328c939fa61792d4b685e8f9047a3a0ad90Adam Powell                    count += ((RouteGroup) route).getRouteCount();
247f7e0a328c939fa61792d4b685e8f9047a3a0ad90Adam Powell                } else {
248f7e0a328c939fa61792d4b685e8f9047a3a0ad90Adam Powell                    count++;
249f7e0a328c939fa61792d4b685e8f9047a3a0ad90Adam Powell                }
250705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell                if ((routeTypes & MediaRouter.ROUTE_TYPE_LIVE_VIDEO) != 0) {
251705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell                    hasVideoRoutes = true;
252705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell                }
253690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            }
254690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
255690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
256690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        setEnabled(count != 0);
257690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
258705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell        // Only allow toggling if we have more than just user routes.
259705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell        // Don't toggle if we support video routes, we may have to let the dialog scan.
260705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell        mToggleMode = count == 2 && (mRouteTypes & MediaRouter.ROUTE_TYPE_LIVE_AUDIO) != 0 &&
261705ab808cf023e0cc38c2ba7cdb9571942cdc04fAdam Powell                !hasVideoRoutes;
262690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
263690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
264690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    @Override
265690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    protected int[] onCreateDrawableState(int extraSpace) {
266690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
2672ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell
2682ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        // Technically we should be handling this more completely, but these
2692ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        // are implementation details here. Checked is used to express the connecting
2702ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        // drawable state and it's mutually exclusive with activated for the purposes
2712ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        // of state selection here.
2722ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        if (mIsConnecting) {
2732ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell            mergeDrawableStates(drawableState, CHECKED_STATE_SET);
2742ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        } else if (mRemoteActive) {
275690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            mergeDrawableStates(drawableState, ACTIVATED_STATE_SET);
276690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
277690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        return drawableState;
278690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
279690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
280690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    @Override
281690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    protected void drawableStateChanged() {
282690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        super.drawableStateChanged();
283690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
284690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        if (mRemoteIndicator != null) {
285690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            int[] myDrawableState = getDrawableState();
286690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            mRemoteIndicator.setState(myDrawableState);
287690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            invalidate();
288690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
289690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
290690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
291690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    @Override
292690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    protected boolean verifyDrawable(Drawable who) {
293690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        return super.verifyDrawable(who) || who == mRemoteIndicator;
294690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
295690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
296690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    @Override
297690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    public void jumpDrawablesToCurrentState() {
298690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        super.jumpDrawablesToCurrentState();
299690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        if (mRemoteIndicator != null) mRemoteIndicator.jumpToCurrentState();
300690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
301690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
302690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    @Override
303690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    public void setVisibility(int visibility) {
304690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        super.setVisibility(visibility);
305690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        if (mRemoteIndicator != null) {
306690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            mRemoteIndicator.setVisible(getVisibility() == VISIBLE, false);
307690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
308690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
309690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
310690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    @Override
311101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich    public void onAttachedToWindow() {
312101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich        super.onAttachedToWindow();
313101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich        mAttachedToWindow = true;
314101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich        if (mRouteTypes != 0) {
315101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich            mRouter.addCallback(mRouteTypes, mRouterCallback);
316101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich            updateRouteInfo();
317101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich        }
318101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich    }
319101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich
320101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich    @Override
321101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich    public void onDetachedFromWindow() {
322101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich        if (mRouteTypes != 0) {
323101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich            mRouter.removeCallback(mRouterCallback);
324101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich        }
325101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich        mAttachedToWindow = false;
326101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich        super.onDetachedFromWindow();
327101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich    }
328101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich
329101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich    @Override
330690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
331690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
332690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
333690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
334690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
335690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
336690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        final int minWidth = Math.max(mMinWidth,
337690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                mRemoteIndicator != null ? mRemoteIndicator.getIntrinsicWidth() : 0);
338690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        final int minHeight = Math.max(mMinHeight,
339690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                mRemoteIndicator != null ? mRemoteIndicator.getIntrinsicHeight() : 0);
340690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
341690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        int width;
342690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        switch (widthMode) {
343690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            case MeasureSpec.EXACTLY:
344690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                width = widthSize;
345690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                break;
346690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            case MeasureSpec.AT_MOST:
347690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                width = Math.min(widthSize, minWidth + getPaddingLeft() + getPaddingRight());
348690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                break;
349690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            default:
350690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            case MeasureSpec.UNSPECIFIED:
351690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                width = minWidth + getPaddingLeft() + getPaddingRight();
352690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                break;
353690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
354690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
355690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        int height;
356690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        switch (heightMode) {
357690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            case MeasureSpec.EXACTLY:
358690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                height = heightSize;
359690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                break;
360690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            case MeasureSpec.AT_MOST:
361690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                height = Math.min(heightSize, minHeight + getPaddingTop() + getPaddingBottom());
362690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                break;
363690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            default:
364690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            case MeasureSpec.UNSPECIFIED:
365690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                height = minHeight + getPaddingTop() + getPaddingBottom();
366690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell                break;
367690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
368690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
369690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        setMeasuredDimension(width, height);
370690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
371690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
372690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    @Override
373690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    protected void onDraw(Canvas canvas) {
374690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        super.onDraw(canvas);
375690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
376690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        if (mRemoteIndicator == null) return;
377690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
378690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        final int left = getPaddingLeft();
379690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        final int right = getWidth() - getPaddingRight();
380690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        final int top = getPaddingTop();
381690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        final int bottom = getHeight() - getPaddingBottom();
382690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
383690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        final int drawWidth = mRemoteIndicator.getIntrinsicWidth();
384690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        final int drawHeight = mRemoteIndicator.getIntrinsicHeight();
385690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        final int drawLeft = left + (right - left - drawWidth) / 2;
386690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        final int drawTop = top + (bottom - top - drawHeight) / 2;
387690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
388690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        mRemoteIndicator.setBounds(drawLeft, drawTop, drawLeft + drawWidth, drawTop + drawHeight);
389690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        mRemoteIndicator.draw(canvas);
390690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
391690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
392b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell    public void setExtendedSettingsClickListener(OnClickListener listener) {
393b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell        mExtendedSettingsClickListener = listener;
39470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        if (mDialogFragment != null) {
39570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell            mDialogFragment.setExtendedSettingsClickListener(listener);
39670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        }
39770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell    }
39870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell
39970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell    /**
40070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell     * Asynchronously show the route chooser dialog.
40170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell     * This will attach a {@link DialogFragment} to the containing Activity.
40270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell     */
40370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell    public void showDialog() {
40470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        final FragmentManager fm = getActivity().getFragmentManager();
40570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        if (mDialogFragment == null) {
40670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell            // See if one is already attached to this activity.
40770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell            mDialogFragment = (MediaRouteChooserDialogFragment) fm.findFragmentByTag(
40870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell                    MediaRouteChooserDialogFragment.FRAGMENT_TAG);
40970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        }
41070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        if (mDialogFragment != null) {
41170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell            Log.w(TAG, "showDialog(): Already showing!");
41270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell            return;
41370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        }
41470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell
41570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        mDialogFragment = new MediaRouteChooserDialogFragment();
41670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        mDialogFragment.setExtendedSettingsClickListener(mExtendedSettingsClickListener);
41770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        mDialogFragment.setLauncherListener(new MediaRouteChooserDialogFragment.LauncherListener() {
41870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell            @Override
41970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell            public void onDetached(MediaRouteChooserDialogFragment detachedFragment) {
42070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell                mDialogFragment = null;
42170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell            }
42270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        });
42370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        mDialogFragment.setRouteTypes(mRouteTypes);
42470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        mDialogFragment.show(fm, MediaRouteChooserDialogFragment.FRAGMENT_TAG);
42570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell    }
42670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell
42770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell    private Activity getActivity() {
42870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        // Gross way of unwrapping the Activity so we can get the FragmentManager
42970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        Context context = getContext();
43070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        while (context instanceof ContextWrapper && !(context instanceof Activity)) {
43170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell            context = ((ContextWrapper) context).getBaseContext();
43270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        }
43370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        if (!(context instanceof Activity)) {
43470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell            throw new IllegalStateException("The MediaRouteButton's Context is not an Activity.");
43570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        }
43670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell
43770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell        return (Activity) context;
438b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell    }
439b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell
440690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    private class MediaRouteCallback extends MediaRouter.SimpleCallback {
441690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        @Override
442d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell        public void onRouteSelected(MediaRouter router, int type, RouteInfo info) {
443690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            updateRemoteIndicator();
444690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
445690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
446690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        @Override
447d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell        public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
448690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            updateRemoteIndicator();
449690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
450690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
451690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        @Override
4522ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        public void onRouteChanged(MediaRouter router, RouteInfo info) {
4532ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell            updateRemoteIndicator();
4542ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        }
4552ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell
4562ee6a2a83262d05a566bd713d238e89edfd33a29Adam Powell        @Override
457d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell        public void onRouteAdded(MediaRouter router, RouteInfo info) {
458690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            updateRouteCount();
459690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
460690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell
461690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        @Override
462d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell        public void onRouteRemoved(MediaRouter router, RouteInfo info) {
463690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell            updateRouteCount();
464690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell        }
465f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell
466f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell        @Override
467f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell        public void onRouteGrouped(MediaRouter router, RouteInfo info, RouteGroup group,
468f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell                int index) {
469f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell            updateRouteCount();
470f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell        }
471f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell
472f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell        @Override
473f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell        public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group) {
474f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell            updateRouteCount();
475f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell        }
476690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell    }
477690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell}
478