MediaRouteButton.java revision 74d762a3ee7dd66fe9ce44f3232159811af8d5d8
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; 26690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.graphics.drawable.Drawable; 27690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.media.MediaRouter; 28f7e0a328c939fa61792d4b685e8f9047a3a0ad90Adam Powellimport android.media.MediaRouter.RouteGroup; 29690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.media.MediaRouter.RouteInfo; 30690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.util.AttributeSet; 31690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.util.Log; 32690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.view.SoundEffectConstants; 33690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellimport android.view.View; 34690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 35690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powellpublic class MediaRouteButton extends View { 36690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private static final String TAG = "MediaRouteButton"; 37690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 38690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private MediaRouter mRouter; 39690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private final MediaRouteCallback mRouterCallback = new MediaRouteCallback(); 40690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private int mRouteTypes; 41690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 42101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich private boolean mAttachedToWindow; 43101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich 44690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private Drawable mRemoteIndicator; 45690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private boolean mRemoteActive; 46690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private boolean mToggleMode; 47690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 48690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private int mMinWidth; 49690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private int mMinHeight; 50690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 51b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell private OnClickListener mExtendedSettingsClickListener; 5270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell private MediaRouteChooserDialogFragment mDialogFragment; 53b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell 54690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private static final int[] ACTIVATED_STATE_SET = { 55690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell R.attr.state_activated 56690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell }; 57690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 58690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public MediaRouteButton(Context context) { 59690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell this(context, null); 60690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 61690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 62690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public MediaRouteButton(Context context, AttributeSet attrs) { 6374d762a3ee7dd66fe9ce44f3232159811af8d5d8Adam Powell this(context, attrs, com.android.internal.R.attr.mediaRouteButtonStyle); 64690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 65690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 66690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public MediaRouteButton(Context context, AttributeSet attrs, int defStyleAttr) { 67690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell super(context, attrs, defStyleAttr); 68690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 69b58b8f832d06b0ffa8886eba5a4916578a3b8743Dianne Hackborn mRouter = (MediaRouter)context.getSystemService(Context.MEDIA_ROUTER_SERVICE); 70690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 71690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell TypedArray a = context.obtainStyledAttributes(attrs, 72690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell com.android.internal.R.styleable.MediaRouteButton, defStyleAttr, 0); 73690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell setRemoteIndicatorDrawable(a.getDrawable( 74690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell com.android.internal.R.styleable.MediaRouteButton_externalRouteEnabledDrawable)); 75690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mMinWidth = a.getDimensionPixelSize( 76690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell com.android.internal.R.styleable.MediaRouteButton_minWidth, 0); 77690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mMinHeight = a.getDimensionPixelSize( 78690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell com.android.internal.R.styleable.MediaRouteButton_minHeight, 0); 79849df0b5a7a5ef72610d687a8b1c2f0a23f873abAdam Powell final int routeTypes = a.getInteger( 80849df0b5a7a5ef72610d687a8b1c2f0a23f873abAdam Powell com.android.internal.R.styleable.MediaRouteButton_mediaRouteTypes, 81849df0b5a7a5ef72610d687a8b1c2f0a23f873abAdam Powell MediaRouter.ROUTE_TYPE_LIVE_AUDIO); 82690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell a.recycle(); 83690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 84690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell setClickable(true); 85849df0b5a7a5ef72610d687a8b1c2f0a23f873abAdam Powell 86849df0b5a7a5ef72610d687a8b1c2f0a23f873abAdam Powell setRouteTypes(routeTypes); 87690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 88690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 89690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private void setRemoteIndicatorDrawable(Drawable d) { 90690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (mRemoteIndicator != null) { 91690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mRemoteIndicator.setCallback(null); 92690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell unscheduleDrawable(mRemoteIndicator); 93690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 94690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mRemoteIndicator = d; 95690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (d != null) { 96690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell d.setCallback(this); 97690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell d.setState(getDrawableState()); 98690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell d.setVisible(getVisibility() == VISIBLE, false); 99690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 100690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 101690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell refreshDrawableState(); 102690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 103690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 104690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 105690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public boolean performClick() { 106690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell // Send the appropriate accessibility events and call listeners 107690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell boolean handled = super.performClick(); 108690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (!handled) { 109690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell playSoundEffect(SoundEffectConstants.CLICK); 110690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 111690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 112690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (mToggleMode) { 113690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (mRemoteActive) { 1140d03c042f90bf62d5bad7c64e77028a5f9f8fae0Adam Powell mRouter.selectRouteInt(mRouteTypes, mRouter.getSystemAudioRoute()); 115690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } else { 116690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int N = mRouter.getRouteCount(); 117690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell for (int i = 0; i < N; i++) { 118690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final RouteInfo route = mRouter.getRouteAt(i); 119690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if ((route.getSupportedTypes() & mRouteTypes) != 0 && 120690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell route != mRouter.getSystemAudioRoute()) { 121eba1b70d7a66fa8299307895ec6d6d6495b387f0Adam Powell mRouter.selectRouteInt(mRouteTypes, route); 122690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 123690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 124690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 125690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } else { 12670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell showDialog(); 127690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 128690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 129690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell return handled; 130690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 131690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 132690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public void setRouteTypes(int types) { 133690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (types == mRouteTypes) { 134690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell // Already registered; nothing to do. 135690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell return; 136690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 137101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich 138101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich if (mAttachedToWindow && mRouteTypes != 0) { 139690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mRouter.removeCallback(mRouterCallback); 140690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 141101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich 142690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mRouteTypes = types; 143101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich 144101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich if (mAttachedToWindow) { 145101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich updateRouteInfo(); 146101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich mRouter.addCallback(types, mRouterCallback); 147101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich } 148101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich } 149101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich 150101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich private void updateRouteInfo() { 151690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell updateRemoteIndicator(); 152690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell updateRouteCount(); 153690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 154690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 155690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public int getRouteTypes() { 156690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell return mRouteTypes; 157690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 158690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 159690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell void updateRemoteIndicator() { 160690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final boolean isRemote = 161690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mRouter.getSelectedRoute(mRouteTypes) != mRouter.getSystemAudioRoute(); 162690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (mRemoteActive != isRemote) { 163690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mRemoteActive = isRemote; 164690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell refreshDrawableState(); 165690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 166690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 167690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 168690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell void updateRouteCount() { 169690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int N = mRouter.getRouteCount(); 170690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell int count = 0; 171690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell for (int i = 0; i < N; i++) { 172f7e0a328c939fa61792d4b685e8f9047a3a0ad90Adam Powell final RouteInfo route = mRouter.getRouteAt(i); 173f7e0a328c939fa61792d4b685e8f9047a3a0ad90Adam Powell if ((route.getSupportedTypes() & mRouteTypes) != 0) { 174f7e0a328c939fa61792d4b685e8f9047a3a0ad90Adam Powell if (route instanceof RouteGroup) { 175f7e0a328c939fa61792d4b685e8f9047a3a0ad90Adam Powell count += ((RouteGroup) route).getRouteCount(); 176f7e0a328c939fa61792d4b685e8f9047a3a0ad90Adam Powell } else { 177f7e0a328c939fa61792d4b685e8f9047a3a0ad90Adam Powell count++; 178f7e0a328c939fa61792d4b685e8f9047a3a0ad90Adam Powell } 179690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 180690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 181690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 182690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell setEnabled(count != 0); 183690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 184690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell // Only allow toggling if we have more than just user routes 185690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mToggleMode = count == 2 && (mRouteTypes & MediaRouter.ROUTE_TYPE_LIVE_AUDIO) != 0; 186690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 187690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 188690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 189690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell protected int[] onCreateDrawableState(int extraSpace) { 190690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int[] drawableState = super.onCreateDrawableState(extraSpace + 1); 191690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (mRemoteActive) { 192690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mergeDrawableStates(drawableState, ACTIVATED_STATE_SET); 193690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 194690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell return drawableState; 195690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 196690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 197690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 198690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell protected void drawableStateChanged() { 199690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell super.drawableStateChanged(); 200690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 201690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (mRemoteIndicator != null) { 202690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell int[] myDrawableState = getDrawableState(); 203690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mRemoteIndicator.setState(myDrawableState); 204690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell invalidate(); 205690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 206690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 207690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 208690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 209690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell protected boolean verifyDrawable(Drawable who) { 210690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell return super.verifyDrawable(who) || who == mRemoteIndicator; 211690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 212690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 213690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 214690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public void jumpDrawablesToCurrentState() { 215690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell super.jumpDrawablesToCurrentState(); 216690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (mRemoteIndicator != null) mRemoteIndicator.jumpToCurrentState(); 217690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 218690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 219690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 220690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell public void setVisibility(int visibility) { 221690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell super.setVisibility(visibility); 222690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (mRemoteIndicator != null) { 223690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mRemoteIndicator.setVisible(getVisibility() == VISIBLE, false); 224690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 225690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 226690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 227690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 228101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich public void onAttachedToWindow() { 229101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich super.onAttachedToWindow(); 230101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich mAttachedToWindow = true; 231101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich if (mRouteTypes != 0) { 232101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich mRouter.addCallback(mRouteTypes, mRouterCallback); 233101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich updateRouteInfo(); 234101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich } 235101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich } 236101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich 237101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich @Override 238101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich public void onDetachedFromWindow() { 239101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich if (mRouteTypes != 0) { 240101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich mRouter.removeCallback(mRouterCallback); 241101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich } 242101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich mAttachedToWindow = false; 243101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich super.onDetachedFromWindow(); 244101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich } 245101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich 246101c44915259fb76d14f917712a51fb0b08a7594Jack Palevich @Override 247690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 248690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int widthSize = MeasureSpec.getSize(widthMeasureSpec); 249690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int heightSize = MeasureSpec.getSize(heightMeasureSpec); 250690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int widthMode = MeasureSpec.getMode(widthMeasureSpec); 251690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int heightMode = MeasureSpec.getMode(heightMeasureSpec); 252690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 253690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int minWidth = Math.max(mMinWidth, 254690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mRemoteIndicator != null ? mRemoteIndicator.getIntrinsicWidth() : 0); 255690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int minHeight = Math.max(mMinHeight, 256690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mRemoteIndicator != null ? mRemoteIndicator.getIntrinsicHeight() : 0); 257690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 258690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell int width; 259690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell switch (widthMode) { 260690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell case MeasureSpec.EXACTLY: 261690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell width = widthSize; 262690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell break; 263690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell case MeasureSpec.AT_MOST: 264690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell width = Math.min(widthSize, minWidth + getPaddingLeft() + getPaddingRight()); 265690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell break; 266690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell default: 267690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell case MeasureSpec.UNSPECIFIED: 268690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell width = minWidth + getPaddingLeft() + getPaddingRight(); 269690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell break; 270690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 271690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 272690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell int height; 273690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell switch (heightMode) { 274690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell case MeasureSpec.EXACTLY: 275690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell height = heightSize; 276690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell break; 277690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell case MeasureSpec.AT_MOST: 278690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell height = Math.min(heightSize, minHeight + getPaddingTop() + getPaddingBottom()); 279690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell break; 280690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell default: 281690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell case MeasureSpec.UNSPECIFIED: 282690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell height = minHeight + getPaddingTop() + getPaddingBottom(); 283690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell break; 284690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 285690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 286690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell setMeasuredDimension(width, height); 287690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 288690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 289690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 290690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell protected void onDraw(Canvas canvas) { 291690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell super.onDraw(canvas); 292690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 293690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell if (mRemoteIndicator == null) return; 294690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 295690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int left = getPaddingLeft(); 296690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int right = getWidth() - getPaddingRight(); 297690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int top = getPaddingTop(); 298690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int bottom = getHeight() - getPaddingBottom(); 299690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 300690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int drawWidth = mRemoteIndicator.getIntrinsicWidth(); 301690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int drawHeight = mRemoteIndicator.getIntrinsicHeight(); 302690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int drawLeft = left + (right - left - drawWidth) / 2; 303690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell final int drawTop = top + (bottom - top - drawHeight) / 2; 304690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 305690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mRemoteIndicator.setBounds(drawLeft, drawTop, drawLeft + drawWidth, drawTop + drawHeight); 306690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell mRemoteIndicator.draw(canvas); 307690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 308690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 309b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell public void setExtendedSettingsClickListener(OnClickListener listener) { 310b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell mExtendedSettingsClickListener = listener; 31170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell if (mDialogFragment != null) { 31270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mDialogFragment.setExtendedSettingsClickListener(listener); 31370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 31470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 31570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 31670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell /** 31770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * Asynchronously show the route chooser dialog. 31870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell * This will attach a {@link DialogFragment} to the containing Activity. 31970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell */ 32070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public void showDialog() { 32170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell final FragmentManager fm = getActivity().getFragmentManager(); 32270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell if (mDialogFragment == null) { 32370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell // See if one is already attached to this activity. 32470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mDialogFragment = (MediaRouteChooserDialogFragment) fm.findFragmentByTag( 32570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell MediaRouteChooserDialogFragment.FRAGMENT_TAG); 32670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 32770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell if (mDialogFragment != null) { 32870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell Log.w(TAG, "showDialog(): Already showing!"); 32970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell return; 33070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 33170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 33270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mDialogFragment = new MediaRouteChooserDialogFragment(); 33370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mDialogFragment.setExtendedSettingsClickListener(mExtendedSettingsClickListener); 33470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mDialogFragment.setLauncherListener(new MediaRouteChooserDialogFragment.LauncherListener() { 33570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell @Override 33670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell public void onDetached(MediaRouteChooserDialogFragment detachedFragment) { 33770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mDialogFragment = null; 33870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 33970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell }); 34070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mDialogFragment.setRouteTypes(mRouteTypes); 34170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell mDialogFragment.show(fm, MediaRouteChooserDialogFragment.FRAGMENT_TAG); 34270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 34370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 34470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell private Activity getActivity() { 34570e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell // Gross way of unwrapping the Activity so we can get the FragmentManager 34670e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell Context context = getContext(); 34770e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell while (context instanceof ContextWrapper && !(context instanceof Activity)) { 34870e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell context = ((ContextWrapper) context).getBaseContext(); 34970e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 35070e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell if (!(context instanceof Activity)) { 35170e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell throw new IllegalStateException("The MediaRouteButton's Context is not an Activity."); 35270e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell } 35370e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell 35470e11e50eecfc8f1dfb76316d099e4331ebd28f7Adam Powell return (Activity) context; 355b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell } 356b35c445f34e1a18e17aef3e3dfbc1c39b4d1815cAdam Powell 357690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell private class MediaRouteCallback extends MediaRouter.SimpleCallback { 358690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 359d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell public void onRouteSelected(MediaRouter router, int type, RouteInfo info) { 360690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell updateRemoteIndicator(); 361690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 362690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 363690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 364d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) { 365690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell updateRemoteIndicator(); 366690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 367690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 368690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 369d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell public void onRouteAdded(MediaRouter router, RouteInfo info) { 370690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell updateRouteCount(); 371690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 372690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell 373690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell @Override 374d0d2cda9d414da73773285d7fee9e13aef3495e9Adam Powell public void onRouteRemoved(MediaRouter router, RouteInfo info) { 375690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell updateRouteCount(); 376690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 377f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell 378f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell @Override 379f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell public void onRouteGrouped(MediaRouter router, RouteInfo info, RouteGroup group, 380f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell int index) { 381f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell updateRouteCount(); 382f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell } 383f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell 384f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell @Override 385f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group) { 386f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell updateRouteCount(); 387f3b653a21cdffe04c94c275e69ecb56e00766e82Adam Powell } 388690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell } 389690ffb4e1f735148a15f2036d9a3c1962fba188cAdam Powell} 390