10abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown/*
20abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * Copyright (C) 2013 The Android Open Source Project
30abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown *
40abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * Licensed under the Apache License, Version 2.0 (the "License");
50abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * you may not use this file except in compliance with the License.
60abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * You may obtain a copy of the License at
70abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown *
80abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown *      http://www.apache.org/licenses/LICENSE-2.0
90abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown *
100abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * Unless required by applicable law or agreed to in writing, software
110abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * distributed under the License is distributed on an "AS IS" BASIS,
120abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * See the License for the specific language governing permissions and
140abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * limitations under the License.
150abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown */
160abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
170abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownpackage com.android.internal.app;
180abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
190abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport com.android.internal.R;
200abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
217980d10d7c1ac0b5301eb8efaa18657201074910Dongwon Kangimport android.app.Dialog;
220abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.app.MediaRouteActionProvider;
230abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.app.MediaRouteButton;
240abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.content.Context;
250abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.graphics.drawable.Drawable;
260abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.media.MediaRouter;
270abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.media.MediaRouter.RouteGroup;
280abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.media.MediaRouter.RouteInfo;
290abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.os.Bundle;
300abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.view.KeyEvent;
310abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.view.View;
320abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.view.Window;
330abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.widget.Button;
340abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.widget.FrameLayout;
350abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.widget.LinearLayout;
360abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brownimport android.widget.SeekBar;
370abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
380abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown/**
390abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * This class implements the route controller dialog for {@link MediaRouter}.
400abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * <p>
410abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * This dialog allows the user to control or disconnect from the currently selected route.
420abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * </p>
430abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown *
440abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * @see MediaRouteButton
450abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * @see MediaRouteActionProvider
460abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown *
470abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown * TODO: Move this back into the API, as in the support library media router.
480abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown */
497980d10d7c1ac0b5301eb8efaa18657201074910Dongwon Kangpublic class MediaRouteControllerDialog extends Dialog {
500abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    // Time to wait before updating the volume when the user lets go of the seek bar
510abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    // to allow the route provider time to propagate the change and publish a new
520abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    // route descriptor.
530abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private static final int VOLUME_UPDATE_DELAY_MILLIS = 250;
540abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
550abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private final MediaRouter mRouter;
560abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private final MediaRouterCallback mCallback;
570abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private final MediaRouter.RouteInfo mRoute;
580abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
590abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private boolean mCreated;
600abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private Drawable mMediaRouteConnectingDrawable;
610abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private Drawable mMediaRouteOnDrawable;
620abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private Drawable mCurrentIconDrawable;
630abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
640abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private boolean mVolumeControlEnabled = true;
650abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private LinearLayout mVolumeLayout;
660abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private SeekBar mVolumeSlider;
670abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private boolean mVolumeSliderTouched;
680abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
690abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private View mControlView;
700abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
710abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private Button mDisconnectButton;
720abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
730abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public MediaRouteControllerDialog(Context context, int theme) {
740abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        super(context, theme);
750abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
760abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mRouter = (MediaRouter) context.getSystemService(Context.MEDIA_ROUTER_SERVICE);
770abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mCallback = new MediaRouterCallback();
780abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mRoute = mRouter.getSelectedRoute();
790abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
800abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
810abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    /**
820abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * Gets the route that this dialog is controlling.
830abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     */
840abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public MediaRouter.RouteInfo getRoute() {
850abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        return mRoute;
860abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
870abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
880abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    /**
890abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * Provides the subclass an opportunity to create a view that will
900abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * be included within the body of the dialog to offer additional media controls
910abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * for the currently playing content.
920abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     *
930abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * @param savedInstanceState The dialog's saved instance state.
940abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * @return The media control view, or null if none.
950abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     */
960abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public View onCreateMediaControlView(Bundle savedInstanceState) {
970abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        return null;
980abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
990abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1000abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    /**
1010abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * Gets the media control view that was created by {@link #onCreateMediaControlView(Bundle)}.
1020abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     *
1030abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * @return The media control view, or null if none.
1040abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     */
1050abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public View getMediaControlView() {
1060abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        return mControlView;
1070abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1080abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1090abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    /**
1100abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * Sets whether to enable the volume slider and volume control using the volume keys
1110abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * when the route supports it.
1120abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * <p>
1130abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * The default value is true.
1140abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * </p>
1150abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     */
1160abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public void setVolumeControlEnabled(boolean enable) {
1170abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        if (mVolumeControlEnabled != enable) {
1180abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            mVolumeControlEnabled = enable;
1190abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            if (mCreated) {
1200abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                updateVolume();
1210abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
1220abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
1230abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1240abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1250abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    /**
1260abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * Returns whether to enable the volume slider and volume control using the volume keys
1270abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     * when the route supports it.
1280abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown     */
1290abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public boolean isVolumeControlEnabled() {
1300abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        return mVolumeControlEnabled;
1310abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
1320abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1330abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    @Override
1340abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    protected void onCreate(Bundle savedInstanceState) {
1350abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        super.onCreate(savedInstanceState);
1360abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1377980d10d7c1ac0b5301eb8efaa18657201074910Dongwon Kang        getWindow().requestFeature(Window.FEATURE_LEFT_ICON);
1387980d10d7c1ac0b5301eb8efaa18657201074910Dongwon Kang
1390abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        setContentView(R.layout.media_route_controller_dialog);
1400abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1410abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mVolumeLayout = (LinearLayout)findViewById(R.id.media_route_volume_layout);
1420abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mVolumeSlider = (SeekBar)findViewById(R.id.media_route_volume_slider);
1430abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mVolumeSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
1440abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            private final Runnable mStopTrackingTouch = new Runnable() {
1450abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                @Override
1460abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                public void run() {
1470abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                    if (mVolumeSliderTouched) {
1480abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                        mVolumeSliderTouched = false;
1490abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                        updateVolume();
1500abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                    }
1510abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                }
1520abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            };
1530abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1540abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            @Override
1550abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            public void onStartTrackingTouch(SeekBar seekBar) {
1560abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                if (mVolumeSliderTouched) {
1570abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                    mVolumeSlider.removeCallbacks(mStopTrackingTouch);
1580abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                } else {
1590abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                    mVolumeSliderTouched = true;
1600abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                }
1610abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
1620abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1630abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            @Override
1640abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            public void onStopTrackingTouch(SeekBar seekBar) {
1650abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                // Defer resetting mVolumeSliderTouched to allow the media route provider
1660abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                // a little time to settle into its new state and publish the final
1670abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                // volume update.
1680abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                mVolumeSlider.postDelayed(mStopTrackingTouch, VOLUME_UPDATE_DELAY_MILLIS);
1690abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
1700abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1710abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            @Override
1720abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
1730abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                if (fromUser) {
1740abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                    mRoute.requestSetVolume(progress);
1750abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                }
1760abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
1770abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        });
1780abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1790abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mDisconnectButton = (Button)findViewById(R.id.media_route_disconnect_button);
1800abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mDisconnectButton.setOnClickListener(new View.OnClickListener() {
1810abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            @Override
1820abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            public void onClick(View v) {
1830abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                if (mRoute.isSelected()) {
1840abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                    mRouter.getDefaultRoute().select();
1850abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                }
1860abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                dismiss();
1870abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
1880abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        });
1890abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
1900abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mCreated = true;
1910abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        if (update()) {
1920abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            mControlView = onCreateMediaControlView(savedInstanceState);
1930abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            FrameLayout controlFrame =
1940abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                    (FrameLayout)findViewById(R.id.media_route_control_frame);
1950abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            if (mControlView != null) {
1960abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                controlFrame.addView(mControlView);
1970abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                controlFrame.setVisibility(View.VISIBLE);
1980abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            } else {
1990abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                controlFrame.setVisibility(View.GONE);
2000abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
2010abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2020abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
2030abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2040abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2050abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    @Override
2060abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public void onAttachedToWindow() {
2070abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        super.onAttachedToWindow();
2080abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2090abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mRouter.addCallback(0, mCallback, MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS);
2100abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        update();
2110abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
2120abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2130abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    @Override
2140abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public void onDetachedFromWindow() {
2150abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        mRouter.removeCallback(mCallback);
2160abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2170abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        super.onDetachedFromWindow();
2180abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
2190abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2200abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    @Override
2210abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public boolean onKeyDown(int keyCode, KeyEvent event) {
2220abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
2230abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
2240abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            mRoute.requestUpdateVolume(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ? -1 : 1);
2250abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            return true;
2260abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2270abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        return super.onKeyDown(keyCode, event);
2280abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
2290abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2300abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    @Override
2310abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    public boolean onKeyUp(int keyCode, KeyEvent event) {
2320abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN
2330abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                || keyCode == KeyEvent.KEYCODE_VOLUME_UP) {
2340abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            return true;
2350abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2360abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        return super.onKeyUp(keyCode, event);
2370abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
2380abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2390abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private boolean update() {
2400abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        if (!mRoute.isSelected() || mRoute.isDefault()) {
2410abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            dismiss();
2420abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            return false;
2430abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2440abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2450abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        setTitle(mRoute.getName());
2460abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        updateVolume();
2470abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2480abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        Drawable icon = getIconDrawable();
2490abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        if (icon != mCurrentIconDrawable) {
2500abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            mCurrentIconDrawable = icon;
2510abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON, icon);
2520abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2530abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        return true;
2540abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
2550abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2560abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private Drawable getIconDrawable() {
2570abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        if (mRoute.isConnecting()) {
2580abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            if (mMediaRouteConnectingDrawable == null) {
2598eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette                mMediaRouteConnectingDrawable = getContext().getDrawable(
2600abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                        R.drawable.ic_media_route_connecting_holo_dark);
2610abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
2620abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            return mMediaRouteConnectingDrawable;
2630abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        } else {
2640abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            if (mMediaRouteOnDrawable == null) {
2658eea3ea5591e59f55cbb4f6b2b7e9363a285ced3Alan Viverette                mMediaRouteOnDrawable = getContext().getDrawable(
2660abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                        R.drawable.ic_media_route_on_holo_dark);
2670abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
2680abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            return mMediaRouteOnDrawable;
2690abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2700abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
2710abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2720abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private void updateVolume() {
2730abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        if (!mVolumeSliderTouched) {
2740abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            if (isVolumeControlAvailable()) {
2750abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                mVolumeLayout.setVisibility(View.VISIBLE);
2760abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                mVolumeSlider.setMax(mRoute.getVolumeMax());
2770abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                mVolumeSlider.setProgress(mRoute.getVolume());
2780abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            } else {
2790abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                mVolumeLayout.setVisibility(View.GONE);
2800abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
2810abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2820abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
2830abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2840abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private boolean isVolumeControlAvailable() {
2850abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        return mVolumeControlEnabled && mRoute.getVolumeHandling() ==
2860abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE;
2870abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
2880abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2890abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    private final class MediaRouterCallback extends MediaRouter.SimpleCallback {
2900abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2910abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void onRouteUnselected(MediaRouter router, int type, RouteInfo info) {
2920abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            update();
2930abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2940abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
2950abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
2960abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo route) {
2970abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            update();
2980abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
2990abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
3000abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
3010abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void onRouteVolumeChanged(MediaRouter router, MediaRouter.RouteInfo route) {
3020abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            if (route == mRoute) {
3030abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                updateVolume();
3040abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            }
3050abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
3060abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
3070abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
3080abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void onRouteGrouped(MediaRouter router, RouteInfo info, RouteGroup group,
3090abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown                int index) {
3100abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            update();
3110abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
3120abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown
3130abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        @Override
3140abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        public void onRouteUngrouped(MediaRouter router, RouteInfo info, RouteGroup group) {
3150abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown            update();
3160abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown        }
3170abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown    }
3180abd3a6ce83ed23abe614155e776b600ef2a66c3Jeff Brown}
319