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