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.content.Context;
2094be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.content.IntentSender;
212ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brownimport android.graphics.drawable.Drawable;
2211417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.os.Bundle;
2394be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.os.RemoteException;
2494be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.MediaDescriptionCompat;
2594be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.MediaMetadataCompat;
2694be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.MediaControllerCompat;
2794be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.MediaSessionCompat;
2894be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.PlaybackStateCompat;
2911417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouteSelector;
3011417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouter;
3111417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.mediarouter.R;
3294be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.text.TextUtils;
3394be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.util.Log;
3411417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.KeyEvent;
3511417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.View;
3611417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.Button;
3711417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.FrameLayout;
3894be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.ImageButton;
3994be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.ImageView;
40f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shahimport android.widget.LinearLayout;
41f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shahimport android.widget.SeekBar;
4294be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.TextView;
4311417b1cfde8f1749905f2d735623af9214148afJeff Brown
4411417b1cfde8f1749905f2d735623af9214148afJeff Brown/**
4511417b1cfde8f1749905f2d735623af9214148afJeff Brown * This class implements the route controller dialog for {@link MediaRouter}.
4611417b1cfde8f1749905f2d735623af9214148afJeff Brown * <p>
4711417b1cfde8f1749905f2d735623af9214148afJeff Brown * This dialog allows the user to control or disconnect from the currently selected route.
4811417b1cfde8f1749905f2d735623af9214148afJeff Brown * </p>
4911417b1cfde8f1749905f2d735623af9214148afJeff Brown *
5011417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see MediaRouteButton
5111417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see MediaRouteActionProvider
5211417b1cfde8f1749905f2d735623af9214148afJeff Brown */
5389530d511efd566d53bedd9178454dd01d227c61Jae Seopublic class MediaRouteControllerDialog extends AlertDialog {
5411417b1cfde8f1749905f2d735623af9214148afJeff Brown    private static final String TAG = "MediaRouteControllerDialog";
5511417b1cfde8f1749905f2d735623af9214148afJeff Brown
56f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    // Time to wait before updating the volume when the user lets go of the seek bar
57f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    // to allow the route provider time to propagate the change and publish a new
58f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    // route descriptor.
59f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    private static final int VOLUME_UPDATE_DELAY_MILLIS = 250;
60f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
6111417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final MediaRouter mRouter;
6211417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final MediaRouterCallback mCallback;
6311417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final MediaRouter.RouteInfo mRoute;
6411417b1cfde8f1749905f2d735623af9214148afJeff Brown
65eff7719415542ba819054863b0995f07742a7a8aJeff Brown    private boolean mCreated;
66e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik    private boolean mAttachedToWindow;
672ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown    private Drawable mMediaRouteConnectingDrawable;
682ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown    private Drawable mMediaRouteOnDrawable;
6911417b1cfde8f1749905f2d735623af9214148afJeff Brown
7011417b1cfde8f1749905f2d735623af9214148afJeff Brown    private View mControlView;
7111417b1cfde8f1749905f2d735623af9214148afJeff Brown
7211417b1cfde8f1749905f2d735623af9214148afJeff Brown    private Button mDisconnectButton;
7394be6100218126ce6a08bf1f56209578500b361fRoboErik    private Button mStopCastingButton;
7494be6100218126ce6a08bf1f56209578500b361fRoboErik    private ImageButton mPlayPauseButton;
7594be6100218126ce6a08bf1f56209578500b361fRoboErik    private ImageButton mSettingsButton;
7694be6100218126ce6a08bf1f56209578500b361fRoboErik
7794be6100218126ce6a08bf1f56209578500b361fRoboErik    private ImageView mArtView;
7894be6100218126ce6a08bf1f56209578500b361fRoboErik    private TextView mTitleView;
7994be6100218126ce6a08bf1f56209578500b361fRoboErik    private TextView mSubtitleView;
8094be6100218126ce6a08bf1f56209578500b361fRoboErik    private TextView mRouteNameView;
8194be6100218126ce6a08bf1f56209578500b361fRoboErik
82f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    private boolean mVolumeControlEnabled = true;
83f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    private LinearLayout mVolumeLayout;
84f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    private SeekBar mVolumeSlider;
85f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    private boolean mVolumeSliderTouched;
86f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
8794be6100218126ce6a08bf1f56209578500b361fRoboErik    private MediaControllerCompat mMediaController;
8894be6100218126ce6a08bf1f56209578500b361fRoboErik    private MediaControllerCallback mControllerCallback;
8994be6100218126ce6a08bf1f56209578500b361fRoboErik    private PlaybackStateCompat mState;
9094be6100218126ce6a08bf1f56209578500b361fRoboErik    private MediaDescriptionCompat mDescription;
9194be6100218126ce6a08bf1f56209578500b361fRoboErik
9211417b1cfde8f1749905f2d735623af9214148afJeff Brown
9311417b1cfde8f1749905f2d735623af9214148afJeff Brown    public MediaRouteControllerDialog(Context context) {
9411417b1cfde8f1749905f2d735623af9214148afJeff Brown        this(context, 0);
9511417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
9611417b1cfde8f1749905f2d735623af9214148afJeff Brown
9711417b1cfde8f1749905f2d735623af9214148afJeff Brown    public MediaRouteControllerDialog(Context context, int theme) {
9894be6100218126ce6a08bf1f56209578500b361fRoboErik        super(MediaRouterThemeHelper.createThemedContext(context), theme);
9911417b1cfde8f1749905f2d735623af9214148afJeff Brown        context = getContext();
10011417b1cfde8f1749905f2d735623af9214148afJeff Brown
10194be6100218126ce6a08bf1f56209578500b361fRoboErik        mControllerCallback = new MediaControllerCallback();
10211417b1cfde8f1749905f2d735623af9214148afJeff Brown        mRouter = MediaRouter.getInstance(context);
10311417b1cfde8f1749905f2d735623af9214148afJeff Brown        mCallback = new MediaRouterCallback();
10411417b1cfde8f1749905f2d735623af9214148afJeff Brown        mRoute = mRouter.getSelectedRoute();
105e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        setMediaSession(mRouter.getMediaSessionToken());
10611417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
10711417b1cfde8f1749905f2d735623af9214148afJeff Brown
10811417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
10911417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Gets the route that this dialog is controlling.
11011417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
11111417b1cfde8f1749905f2d735623af9214148afJeff Brown    public MediaRouter.RouteInfo getRoute() {
11211417b1cfde8f1749905f2d735623af9214148afJeff Brown        return mRoute;
11311417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
11411417b1cfde8f1749905f2d735623af9214148afJeff Brown
11511417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
11611417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Provides the subclass an opportunity to create a view that will
11711417b1cfde8f1749905f2d735623af9214148afJeff Brown     * be included within the body of the dialog to offer additional media controls
11811417b1cfde8f1749905f2d735623af9214148afJeff Brown     * for the currently playing content.
11911417b1cfde8f1749905f2d735623af9214148afJeff Brown     *
12011417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @param savedInstanceState The dialog's saved instance state.
12111417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @return The media control view, or null if none.
12211417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
12311417b1cfde8f1749905f2d735623af9214148afJeff Brown    public View onCreateMediaControlView(Bundle savedInstanceState) {
12411417b1cfde8f1749905f2d735623af9214148afJeff Brown        return null;
12511417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
12611417b1cfde8f1749905f2d735623af9214148afJeff Brown
12711417b1cfde8f1749905f2d735623af9214148afJeff Brown    /**
12811417b1cfde8f1749905f2d735623af9214148afJeff Brown     * Gets the media control view that was created by {@link #onCreateMediaControlView(Bundle)}.
12911417b1cfde8f1749905f2d735623af9214148afJeff Brown     *
13011417b1cfde8f1749905f2d735623af9214148afJeff Brown     * @return The media control view, or null if none.
13111417b1cfde8f1749905f2d735623af9214148afJeff Brown     */
13211417b1cfde8f1749905f2d735623af9214148afJeff Brown    public View getMediaControlView() {
13311417b1cfde8f1749905f2d735623af9214148afJeff Brown        return mControlView;
13411417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
13511417b1cfde8f1749905f2d735623af9214148afJeff Brown
136eff7719415542ba819054863b0995f07742a7a8aJeff Brown    /**
137f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * Sets whether to enable the volume slider and volume control using the volume keys
138f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * when the route supports it.
139f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * <p>
140f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * The default value is true.
141f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * </p>
142f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     */
143f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    public void setVolumeControlEnabled(boolean enable) {
144f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        if (mVolumeControlEnabled != enable) {
145f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            mVolumeControlEnabled = enable;
146f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            if (mCreated) {
147f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                updateVolume();
148f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            }
149f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        }
150f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    }
151f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
152f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    /**
153f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * Returns whether to enable the volume slider and volume control using the volume keys
154f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     * when the route supports it.
155f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah     */
156f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    public boolean isVolumeControlEnabled() {
157f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        return mVolumeControlEnabled;
158f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    }
159f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
160f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    /**
16194be6100218126ce6a08bf1f56209578500b361fRoboErik     * Set the session to use for metadata and transport controls. The dialog
16294be6100218126ce6a08bf1f56209578500b361fRoboErik     * will listen to changes on this session and update the UI automatically in
16394be6100218126ce6a08bf1f56209578500b361fRoboErik     * response to changes.
16494be6100218126ce6a08bf1f56209578500b361fRoboErik     *
16594be6100218126ce6a08bf1f56209578500b361fRoboErik     * @param sessionToken The token for the session to use.
166eff7719415542ba819054863b0995f07742a7a8aJeff Brown     */
167e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik    private void setMediaSession(MediaSessionCompat.Token sessionToken) {
16894be6100218126ce6a08bf1f56209578500b361fRoboErik        if (mMediaController != null) {
16994be6100218126ce6a08bf1f56209578500b361fRoboErik            mMediaController.unregisterCallback(mControllerCallback);
17094be6100218126ce6a08bf1f56209578500b361fRoboErik            mMediaController = null;
17194be6100218126ce6a08bf1f56209578500b361fRoboErik        }
17294be6100218126ce6a08bf1f56209578500b361fRoboErik        if (sessionToken == null) {
17394be6100218126ce6a08bf1f56209578500b361fRoboErik            return;
17494be6100218126ce6a08bf1f56209578500b361fRoboErik        }
175e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        if (!mAttachedToWindow) {
176e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik            return;
177e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        }
17894be6100218126ce6a08bf1f56209578500b361fRoboErik        try {
17994be6100218126ce6a08bf1f56209578500b361fRoboErik            mMediaController = new MediaControllerCompat(getContext(), sessionToken);
18094be6100218126ce6a08bf1f56209578500b361fRoboErik        } catch (RemoteException e) {
18194be6100218126ce6a08bf1f56209578500b361fRoboErik            Log.e(TAG, "Error creating media controller in setMediaSession.", e);
18294be6100218126ce6a08bf1f56209578500b361fRoboErik        }
18394be6100218126ce6a08bf1f56209578500b361fRoboErik        if (mMediaController != null) {
18494be6100218126ce6a08bf1f56209578500b361fRoboErik            mMediaController.registerCallback(mControllerCallback);
185eff7719415542ba819054863b0995f07742a7a8aJeff Brown        }
18694be6100218126ce6a08bf1f56209578500b361fRoboErik        MediaMetadataCompat metadata = mMediaController == null ? null
18794be6100218126ce6a08bf1f56209578500b361fRoboErik                : mMediaController.getMetadata();
18894be6100218126ce6a08bf1f56209578500b361fRoboErik        mDescription = metadata == null ? null : metadata.getDescription();
18994be6100218126ce6a08bf1f56209578500b361fRoboErik        mState = mMediaController == null ? null : mMediaController.getPlaybackState();
19094be6100218126ce6a08bf1f56209578500b361fRoboErik        update();
191eff7719415542ba819054863b0995f07742a7a8aJeff Brown    }
192eff7719415542ba819054863b0995f07742a7a8aJeff Brown
193eff7719415542ba819054863b0995f07742a7a8aJeff Brown    /**
19494be6100218126ce6a08bf1f56209578500b361fRoboErik     * Gets the description being used by the default UI.
19594be6100218126ce6a08bf1f56209578500b361fRoboErik     *
19694be6100218126ce6a08bf1f56209578500b361fRoboErik     * @return The current description.
197eff7719415542ba819054863b0995f07742a7a8aJeff Brown     */
19894be6100218126ce6a08bf1f56209578500b361fRoboErik    public MediaSessionCompat.Token getMediaSession() {
19994be6100218126ce6a08bf1f56209578500b361fRoboErik        return mMediaController == null ? null : mMediaController.getSessionToken();
200eff7719415542ba819054863b0995f07742a7a8aJeff Brown    }
201eff7719415542ba819054863b0995f07742a7a8aJeff Brown
20211417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
20311417b1cfde8f1749905f2d735623af9214148afJeff Brown    protected void onCreate(Bundle savedInstanceState) {
20411417b1cfde8f1749905f2d735623af9214148afJeff Brown        super.onCreate(savedInstanceState);
20511417b1cfde8f1749905f2d735623af9214148afJeff Brown
20694be6100218126ce6a08bf1f56209578500b361fRoboErik        setContentView(R.layout.mr_media_route_controller_material_dialog_b);
20711417b1cfde8f1749905f2d735623af9214148afJeff Brown
20894be6100218126ce6a08bf1f56209578500b361fRoboErik        ClickListener listener = new ClickListener();
209d6748a7926ebb2450337f9f0ff4d445c980344e5Jeff Brown
21094be6100218126ce6a08bf1f56209578500b361fRoboErik        mDisconnectButton = (Button) findViewById(R.id.disconnect);
21194be6100218126ce6a08bf1f56209578500b361fRoboErik        mDisconnectButton.setOnClickListener(listener);
21211417b1cfde8f1749905f2d735623af9214148afJeff Brown
21394be6100218126ce6a08bf1f56209578500b361fRoboErik        mStopCastingButton = (Button) findViewById(R.id.stop);
21494be6100218126ce6a08bf1f56209578500b361fRoboErik        mStopCastingButton.setOnClickListener(listener);
21511417b1cfde8f1749905f2d735623af9214148afJeff Brown
21694be6100218126ce6a08bf1f56209578500b361fRoboErik        mSettingsButton = (ImageButton) findViewById(R.id.settings);
21794be6100218126ce6a08bf1f56209578500b361fRoboErik        mSettingsButton.setOnClickListener(listener);
21811417b1cfde8f1749905f2d735623af9214148afJeff Brown
21994be6100218126ce6a08bf1f56209578500b361fRoboErik        mArtView = (ImageView) findViewById(R.id.art);
22094be6100218126ce6a08bf1f56209578500b361fRoboErik        mTitleView = (TextView) findViewById(R.id.title);
22194be6100218126ce6a08bf1f56209578500b361fRoboErik        mSubtitleView = (TextView) findViewById(R.id.subtitle);
22294be6100218126ce6a08bf1f56209578500b361fRoboErik        mPlayPauseButton = (ImageButton) findViewById(R.id.play_pause);
22394be6100218126ce6a08bf1f56209578500b361fRoboErik        mPlayPauseButton.setOnClickListener(listener);
22494be6100218126ce6a08bf1f56209578500b361fRoboErik        mRouteNameView = (TextView) findViewById(R.id.route_name);
225f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        mVolumeLayout = (LinearLayout)findViewById(R.id.media_route_volume_layout);
226f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        mVolumeSlider = (SeekBar)findViewById(R.id.media_route_volume_slider);
227f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        mVolumeSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
228f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            private final Runnable mStopTrackingTouch = new Runnable() {
229f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                @Override
230f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                public void run() {
231f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                    if (mVolumeSliderTouched) {
232f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                        mVolumeSliderTouched = false;
233f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                        updateVolume();
234f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                    }
235f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                }
236f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            };
237f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
238f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            @Override
239f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            public void onStartTrackingTouch(SeekBar seekBar) {
240f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                if (mVolumeSliderTouched) {
241f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                    mVolumeSlider.removeCallbacks(mStopTrackingTouch);
242f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                } else {
243f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                    mVolumeSliderTouched = true;
244f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                }
245f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            }
246f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
247f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            @Override
248f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            public void onStopTrackingTouch(SeekBar seekBar) {
249f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                // Defer resetting mVolumeSliderTouched to allow the media route provider
250f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                // a little time to settle into its new state and publish the final
251f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                // volume update.
252f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                mVolumeSlider.postDelayed(mStopTrackingTouch, VOLUME_UPDATE_DELAY_MILLIS);
253f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            }
254f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
255f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            @Override
256f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
257f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                if (fromUser) {
258f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                    mRoute.requestSetVolume(progress);
259f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                }
260f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            }
261f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        });
26211417b1cfde8f1749905f2d735623af9214148afJeff Brown
263eff7719415542ba819054863b0995f07742a7a8aJeff Brown        mCreated = true;
26411417b1cfde8f1749905f2d735623af9214148afJeff Brown        if (update()) {
26511417b1cfde8f1749905f2d735623af9214148afJeff Brown            mControlView = onCreateMediaControlView(savedInstanceState);
266697ff1cbd5efee431fb10c74b31071cf95341203Prameet Shah            FrameLayout controlFrame =
267697ff1cbd5efee431fb10c74b31071cf95341203Prameet Shah                    (FrameLayout)findViewById(R.id.media_route_control_frame);
26811417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (mControlView != null) {
26994be6100218126ce6a08bf1f56209578500b361fRoboErik                controlFrame.findViewById(R.id.default_control_frame).setVisibility(View.GONE);
270697ff1cbd5efee431fb10c74b31071cf95341203Prameet Shah                controlFrame.addView(mControlView);
27111417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
27211417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
27311417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
27411417b1cfde8f1749905f2d735623af9214148afJeff Brown
27511417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
27611417b1cfde8f1749905f2d735623af9214148afJeff Brown    public void onAttachedToWindow() {
27711417b1cfde8f1749905f2d735623af9214148afJeff Brown        super.onAttachedToWindow();
278e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        mAttachedToWindow = true;
27911417b1cfde8f1749905f2d735623af9214148afJeff Brown
28011417b1cfde8f1749905f2d735623af9214148afJeff Brown        mRouter.addCallback(MediaRouteSelector.EMPTY, mCallback,
28111417b1cfde8f1749905f2d735623af9214148afJeff Brown                MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS);
282e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        setMediaSession(mRouter.getMediaSessionToken());
28311417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
28411417b1cfde8f1749905f2d735623af9214148afJeff Brown
28511417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
28611417b1cfde8f1749905f2d735623af9214148afJeff Brown    public void onDetachedFromWindow() {
28711417b1cfde8f1749905f2d735623af9214148afJeff Brown        mRouter.removeCallback(mCallback);
288e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        setMediaSession(null);
289e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik        mAttachedToWindow = false;
29011417b1cfde8f1749905f2d735623af9214148afJeff Brown        super.onDetachedFromWindow();
29111417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
29211417b1cfde8f1749905f2d735623af9214148afJeff Brown
29311417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
29411417b1cfde8f1749905f2d735623af9214148afJeff Brown    public boolean onKeyDown(int keyCode, KeyEvent event) {
295ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
296ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown                || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
297ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown            mRoute.requestUpdateVolume(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ? -1 : 1);
298ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown            return true;
29911417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
30011417b1cfde8f1749905f2d735623af9214148afJeff Brown        return super.onKeyDown(keyCode, event);
30111417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
30211417b1cfde8f1749905f2d735623af9214148afJeff Brown
30311417b1cfde8f1749905f2d735623af9214148afJeff Brown    @Override
30411417b1cfde8f1749905f2d735623af9214148afJeff Brown    public boolean onKeyUp(int keyCode, KeyEvent event) {
305ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
306ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown                || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
307ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown            return true;
30811417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
30911417b1cfde8f1749905f2d735623af9214148afJeff Brown        return super.onKeyUp(keyCode, event);
31011417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
31111417b1cfde8f1749905f2d735623af9214148afJeff Brown
31211417b1cfde8f1749905f2d735623af9214148afJeff Brown    private boolean update() {
31311417b1cfde8f1749905f2d735623af9214148afJeff Brown        if (!mRoute.isSelected() || mRoute.isDefault()) {
31411417b1cfde8f1749905f2d735623af9214148afJeff Brown            dismiss();
31511417b1cfde8f1749905f2d735623af9214148afJeff Brown            return false;
31611417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
31794be6100218126ce6a08bf1f56209578500b361fRoboErik        if (!mCreated) {
31894be6100218126ce6a08bf1f56209578500b361fRoboErik            return false;
31994be6100218126ce6a08bf1f56209578500b361fRoboErik        }
32011417b1cfde8f1749905f2d735623af9214148afJeff Brown
321f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        updateVolume();
322f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
32394be6100218126ce6a08bf1f56209578500b361fRoboErik        mRouteNameView.setText(mRoute.getName());
32411417b1cfde8f1749905f2d735623af9214148afJeff Brown
32594be6100218126ce6a08bf1f56209578500b361fRoboErik        if (mRoute.canDisconnect()) {
32694be6100218126ce6a08bf1f56209578500b361fRoboErik            mDisconnectButton.setVisibility(View.VISIBLE);
32794be6100218126ce6a08bf1f56209578500b361fRoboErik        } else {
32894be6100218126ce6a08bf1f56209578500b361fRoboErik            mDisconnectButton.setVisibility(View.GONE);
32994be6100218126ce6a08bf1f56209578500b361fRoboErik        }
3302ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown
33194be6100218126ce6a08bf1f56209578500b361fRoboErik        if (mRoute.getSettingsIntent() != null) {
33294be6100218126ce6a08bf1f56209578500b361fRoboErik            mSettingsButton.setVisibility(View.VISIBLE);
33394be6100218126ce6a08bf1f56209578500b361fRoboErik        } else {
33494be6100218126ce6a08bf1f56209578500b361fRoboErik            mSettingsButton.setVisibility(View.GONE);
33594be6100218126ce6a08bf1f56209578500b361fRoboErik        }
33694be6100218126ce6a08bf1f56209578500b361fRoboErik
33794be6100218126ce6a08bf1f56209578500b361fRoboErik        if (mControlView == null) {
33866937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang            if (mDescription != null && mDescription.getIconBitmap() != null) {
33966937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang                mArtView.setImageBitmap(mDescription.getIconBitmap());
34066937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang                mArtView.setVisibility(View.VISIBLE);
34166937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang            } else if (mDescription != null && mDescription.getIconUri() != null) {
34266937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang                // TODO replace with background load of icon
34366937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang                mArtView.setImageURI(mDescription.getIconUri());
34466937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang                mArtView.setVisibility(View.VISIBLE);
34566937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang            } else {
34666937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang                mArtView.setImageDrawable(null);
34766937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang                mArtView.setVisibility(View.GONE);
34866937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang            }
3495db1d51338a41b1dab537a5a37a0de8f5f0cc5b9Jae Seo
35066937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang            CharSequence title = mDescription == null ? null : mDescription.getTitle();
35166937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang            boolean hasTitle = !TextUtils.isEmpty(title);
35266937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang
35366937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang            CharSequence subtitle = mDescription == null ? null : mDescription.getSubtitle();
35466937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang            boolean hasSubtitle = !TextUtils.isEmpty(subtitle);
35566937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang
35666937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang            if (!hasTitle && !hasSubtitle) {
35766937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang                mTitleView.setText(R.string.mr_media_route_controller_no_info_available);
35866937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang                mTitleView.setEnabled(false);
35966937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang                mTitleView.setVisibility(View.VISIBLE);
36066937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang                mSubtitleView.setVisibility(View.GONE);
36166937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang            } else {
36266937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang                mTitleView.setText(title);
36366937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang                mTitleView.setEnabled(hasTitle);
36466937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang                mTitleView.setVisibility(hasTitle ? View.VISIBLE : View.GONE);
36566937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang                mSubtitleView.setText(subtitle);
36666937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang                mSubtitleView.setVisibility(hasSubtitle ? View.VISIBLE : View.GONE);
36794be6100218126ce6a08bf1f56209578500b361fRoboErik            }
36894be6100218126ce6a08bf1f56209578500b361fRoboErik            if (mState != null) {
36994be6100218126ce6a08bf1f56209578500b361fRoboErik                boolean isPlaying = mState.getState() == PlaybackStateCompat.STATE_BUFFERING
37094be6100218126ce6a08bf1f56209578500b361fRoboErik                        || mState.getState() == PlaybackStateCompat.STATE_PLAYING;
37194be6100218126ce6a08bf1f56209578500b361fRoboErik                boolean supportsPlay = (mState.getActions() & (PlaybackStateCompat.ACTION_PLAY
37294be6100218126ce6a08bf1f56209578500b361fRoboErik                        | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0;
37394be6100218126ce6a08bf1f56209578500b361fRoboErik                boolean supportsPause = (mState.getActions() & (PlaybackStateCompat.ACTION_PAUSE
37494be6100218126ce6a08bf1f56209578500b361fRoboErik                                | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0;
37594be6100218126ce6a08bf1f56209578500b361fRoboErik                if (isPlaying && supportsPause) {
37694be6100218126ce6a08bf1f56209578500b361fRoboErik                    mPlayPauseButton.setVisibility(View.VISIBLE);
37792badabc6a274e3bf8ea2a0072e8a6371f252722RoboErik                    mPlayPauseButton.setImageResource(MediaRouterThemeHelper.getThemeResource(
37892badabc6a274e3bf8ea2a0072e8a6371f252722RoboErik                            getContext(), R.attr.mediaRoutePauseDrawable));
37994be6100218126ce6a08bf1f56209578500b361fRoboErik                    mPlayPauseButton.setContentDescription(getContext().getResources()
38094be6100218126ce6a08bf1f56209578500b361fRoboErik                            .getText(R.string.mr_media_route_controller_pause));
38194be6100218126ce6a08bf1f56209578500b361fRoboErik                } else if (!isPlaying && supportsPlay) {
38294be6100218126ce6a08bf1f56209578500b361fRoboErik                    mPlayPauseButton.setVisibility(View.VISIBLE);
38392badabc6a274e3bf8ea2a0072e8a6371f252722RoboErik                    mPlayPauseButton.setImageResource(MediaRouterThemeHelper.getThemeResource(
38492badabc6a274e3bf8ea2a0072e8a6371f252722RoboErik                            getContext(), R.attr.mediaRoutePlayDrawable));
38594be6100218126ce6a08bf1f56209578500b361fRoboErik                    mPlayPauseButton.setContentDescription(getContext().getResources()
38694be6100218126ce6a08bf1f56209578500b361fRoboErik                            .getText(R.string.mr_media_route_controller_play));
38794be6100218126ce6a08bf1f56209578500b361fRoboErik                } else {
38894be6100218126ce6a08bf1f56209578500b361fRoboErik                    mPlayPauseButton.setVisibility(View.GONE);
38994be6100218126ce6a08bf1f56209578500b361fRoboErik                }
39094be6100218126ce6a08bf1f56209578500b361fRoboErik            } else {
39194be6100218126ce6a08bf1f56209578500b361fRoboErik                mPlayPauseButton.setVisibility(View.GONE);
39294be6100218126ce6a08bf1f56209578500b361fRoboErik            }
3932ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown        }
39411417b1cfde8f1749905f2d735623af9214148afJeff Brown        return true;
39511417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
39611417b1cfde8f1749905f2d735623af9214148afJeff Brown
3972ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown    private Drawable getIconDrawable() {
3982ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown        if (mRoute.isConnecting()) {
3992ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown            if (mMediaRouteConnectingDrawable == null) {
4002ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown                mMediaRouteConnectingDrawable = MediaRouterThemeHelper.getThemeDrawable(
4012ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown                        getContext(), R.attr.mediaRouteConnectingDrawable);
4022ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown            }
4032ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown            return mMediaRouteConnectingDrawable;
4042ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown        } else {
4052ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown            if (mMediaRouteOnDrawable == null) {
4062ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown                mMediaRouteOnDrawable = MediaRouterThemeHelper.getThemeDrawable(
4072ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown                        getContext(), R.attr.mediaRouteOnDrawable);
4082ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown            }
4092ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown            return mMediaRouteOnDrawable;
4102ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown        }
4112ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown    }
4122ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown
413f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    private void updateVolume() {
414f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        if (!mVolumeSliderTouched) {
415f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            if (isVolumeControlAvailable()) {
416f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                mVolumeLayout.setVisibility(View.VISIBLE);
417f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                mVolumeSlider.setMax(mRoute.getVolumeMax());
418f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                mVolumeSlider.setProgress(mRoute.getVolume());
419f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            } else {
420f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                mVolumeLayout.setVisibility(View.GONE);
421f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah            }
422f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        }
423f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    }
424f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
425f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    private boolean isVolumeControlAvailable() {
426f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah        return mVolumeControlEnabled && mRoute.getVolumeHandling() ==
427f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE;
428f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah    }
429f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah
43011417b1cfde8f1749905f2d735623af9214148afJeff Brown    private final class MediaRouterCallback extends MediaRouter.Callback {
43111417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
43211417b1cfde8f1749905f2d735623af9214148afJeff Brown        public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route) {
43311417b1cfde8f1749905f2d735623af9214148afJeff Brown            update();
43411417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
43511417b1cfde8f1749905f2d735623af9214148afJeff Brown
43611417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
43711417b1cfde8f1749905f2d735623af9214148afJeff Brown        public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo route) {
43811417b1cfde8f1749905f2d735623af9214148afJeff Brown            update();
43911417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
44011417b1cfde8f1749905f2d735623af9214148afJeff Brown
44111417b1cfde8f1749905f2d735623af9214148afJeff Brown        @Override
44211417b1cfde8f1749905f2d735623af9214148afJeff Brown        public void onRouteVolumeChanged(MediaRouter router, MediaRouter.RouteInfo route) {
44311417b1cfde8f1749905f2d735623af9214148afJeff Brown            if (route == mRoute) {
444f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah                updateVolume();
44594be6100218126ce6a08bf1f56209578500b361fRoboErik            }
44694be6100218126ce6a08bf1f56209578500b361fRoboErik        }
44794be6100218126ce6a08bf1f56209578500b361fRoboErik    }
44894be6100218126ce6a08bf1f56209578500b361fRoboErik
44994be6100218126ce6a08bf1f56209578500b361fRoboErik    private final class MediaControllerCallback extends MediaControllerCompat.Callback {
45094be6100218126ce6a08bf1f56209578500b361fRoboErik        @Override
45194be6100218126ce6a08bf1f56209578500b361fRoboErik        public void onSessionDestroyed() {
45294be6100218126ce6a08bf1f56209578500b361fRoboErik            if (mMediaController != null) {
45394be6100218126ce6a08bf1f56209578500b361fRoboErik                mMediaController.unregisterCallback(mControllerCallback);
45494be6100218126ce6a08bf1f56209578500b361fRoboErik                mMediaController = null;
45594be6100218126ce6a08bf1f56209578500b361fRoboErik            }
45694be6100218126ce6a08bf1f56209578500b361fRoboErik        }
45794be6100218126ce6a08bf1f56209578500b361fRoboErik
45894be6100218126ce6a08bf1f56209578500b361fRoboErik        @Override
45994be6100218126ce6a08bf1f56209578500b361fRoboErik        public void onPlaybackStateChanged(PlaybackStateCompat state) {
46094be6100218126ce6a08bf1f56209578500b361fRoboErik            mState = state;
46194be6100218126ce6a08bf1f56209578500b361fRoboErik            update();
46294be6100218126ce6a08bf1f56209578500b361fRoboErik        }
46394be6100218126ce6a08bf1f56209578500b361fRoboErik
46494be6100218126ce6a08bf1f56209578500b361fRoboErik        @Override
46594be6100218126ce6a08bf1f56209578500b361fRoboErik        public void onMetadataChanged(MediaMetadataCompat metadata) {
46694be6100218126ce6a08bf1f56209578500b361fRoboErik            mDescription = metadata == null ? null : metadata.getDescription();
46794be6100218126ce6a08bf1f56209578500b361fRoboErik            update();
46894be6100218126ce6a08bf1f56209578500b361fRoboErik        }
46994be6100218126ce6a08bf1f56209578500b361fRoboErik    }
47094be6100218126ce6a08bf1f56209578500b361fRoboErik
47194be6100218126ce6a08bf1f56209578500b361fRoboErik    private final class ClickListener implements View.OnClickListener {
47294be6100218126ce6a08bf1f56209578500b361fRoboErik        @Override
47394be6100218126ce6a08bf1f56209578500b361fRoboErik        public void onClick(View v) {
47494be6100218126ce6a08bf1f56209578500b361fRoboErik            int id = v.getId();
47594be6100218126ce6a08bf1f56209578500b361fRoboErik            if (id == R.id.stop || id == R.id.disconnect) {
47694be6100218126ce6a08bf1f56209578500b361fRoboErik                if (mRoute.isSelected()) {
47794be6100218126ce6a08bf1f56209578500b361fRoboErik                    mRouter.unselect(id == R.id.stop ?
47894be6100218126ce6a08bf1f56209578500b361fRoboErik                            MediaRouter.UNSELECT_REASON_STOPPED :
47994be6100218126ce6a08bf1f56209578500b361fRoboErik                            MediaRouter.UNSELECT_REASON_DISCONNECTED);
48094be6100218126ce6a08bf1f56209578500b361fRoboErik                }
48194be6100218126ce6a08bf1f56209578500b361fRoboErik                dismiss();
48294be6100218126ce6a08bf1f56209578500b361fRoboErik            } else if (id == R.id.play_pause) {
48394be6100218126ce6a08bf1f56209578500b361fRoboErik                if (mMediaController != null && mState != null) {
48494be6100218126ce6a08bf1f56209578500b361fRoboErik                    if (mState.getState() == PlaybackStateCompat.STATE_PLAYING) {
48594be6100218126ce6a08bf1f56209578500b361fRoboErik                        mMediaController.getTransportControls().pause();
48694be6100218126ce6a08bf1f56209578500b361fRoboErik                    } else {
48794be6100218126ce6a08bf1f56209578500b361fRoboErik                        mMediaController.getTransportControls().play();
48894be6100218126ce6a08bf1f56209578500b361fRoboErik                    }
48994be6100218126ce6a08bf1f56209578500b361fRoboErik                }
49094be6100218126ce6a08bf1f56209578500b361fRoboErik            } else if (id == R.id.settings) {
49194be6100218126ce6a08bf1f56209578500b361fRoboErik                IntentSender is = mRoute.getSettingsIntent();
49294be6100218126ce6a08bf1f56209578500b361fRoboErik                if (is != null) {
49394be6100218126ce6a08bf1f56209578500b361fRoboErik                    try {
49494be6100218126ce6a08bf1f56209578500b361fRoboErik                        is.sendIntent(null, 0, null, null, null);
49594be6100218126ce6a08bf1f56209578500b361fRoboErik                        dismiss();
49694be6100218126ce6a08bf1f56209578500b361fRoboErik                    } catch (Exception e) {
49794be6100218126ce6a08bf1f56209578500b361fRoboErik                        Log.e(TAG, "Error opening route settings.", e);
49894be6100218126ce6a08bf1f56209578500b361fRoboErik                    }
49994be6100218126ce6a08bf1f56209578500b361fRoboErik                }
50011417b1cfde8f1749905f2d735623af9214148afJeff Brown            }
50111417b1cfde8f1749905f2d735623af9214148afJeff Brown        }
50211417b1cfde8f1749905f2d735623af9214148afJeff Brown    }
50311417b1cfde8f1749905f2d735623af9214148afJeff Brown}
504