MediaRouteControllerDialog.java revision 8367dca195f881c38fbaf69a5d533a6cca820471
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 19bfb90b6717bb46535d747aa50045a206965542d0Jae Seoimport static android.widget.SeekBar.OnSeekBarChangeListener; 20bfb90b6717bb46535d747aa50045a206965542d0Jae Seo 21005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.content.ContentResolver; 2211417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.content.Context; 236051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.content.res.TypedArray; 24005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.graphics.Bitmap; 25005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.graphics.BitmapFactory; 2686a802c8d09983d8725cccf59217e65d3e0c6373Jae Seoimport android.graphics.PorterDuff; 272c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kimimport android.graphics.Rect; 2813d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kimimport android.graphics.drawable.BitmapDrawable; 292ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brownimport android.graphics.drawable.Drawable; 30005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.net.Uri; 31005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.os.AsyncTask; 32418c688351713e9349227262163eef752a8e7ce6Jae Seoimport android.os.Build; 3311417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.os.Bundle; 3494be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.os.RemoteException; 3594be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.MediaDescriptionCompat; 3694be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.MediaMetadataCompat; 3794be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.MediaControllerCompat; 3894be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.MediaSessionCompat; 3994be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.PlaybackStateCompat; 40005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.support.v7.graphics.Palette; 4111417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouteSelector; 4211417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouter; 43418c688351713e9349227262163eef752a8e7ce6Jae Seoimport android.support.v7.media.SeekBarJellybean; 4411417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.mediarouter.R; 4594be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.text.TextUtils; 4694be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.util.Log; 4706991009e52024cbb3dde550988e06149e77a269Jae Seoimport android.util.TypedValue; 4811417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.KeyEvent; 496051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.view.LayoutInflater; 5011417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.View; 5140dd800ece983a94ea6a26a27481da50f489e7c8Jaewan Kimimport android.view.View.MeasureSpec; 526051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.view.ViewGroup; 536051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.widget.ArrayAdapter; 5411417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.Button; 5511417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.FrameLayout; 5694be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.ImageButton; 5794be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.ImageView; 58f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shahimport android.widget.LinearLayout; 596051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.widget.ListView; 607ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Limimport android.widget.RelativeLayout; 61f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shahimport android.widget.SeekBar; 6294be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.TextView; 6311417b1cfde8f1749905f2d735623af9214148afJeff Brown 64005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport java.io.BufferedInputStream; 65005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport java.io.IOException; 666051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport java.util.List; 67005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 6811417b1cfde8f1749905f2d735623af9214148afJeff Brown/** 6911417b1cfde8f1749905f2d735623af9214148afJeff Brown * This class implements the route controller dialog for {@link MediaRouter}. 7011417b1cfde8f1749905f2d735623af9214148afJeff Brown * <p> 7111417b1cfde8f1749905f2d735623af9214148afJeff Brown * This dialog allows the user to control or disconnect from the currently selected route. 7211417b1cfde8f1749905f2d735623af9214148afJeff Brown * </p> 7311417b1cfde8f1749905f2d735623af9214148afJeff Brown * 7411417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see MediaRouteButton 7511417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see MediaRouteActionProvider 7611417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 7789530d511efd566d53bedd9178454dd01d227c61Jae Seopublic class MediaRouteControllerDialog extends AlertDialog { 7811417b1cfde8f1749905f2d735623af9214148afJeff Brown private static final String TAG = "MediaRouteControllerDialog"; 7911417b1cfde8f1749905f2d735623af9214148afJeff Brown 80a4bcfe765789ebef71c36cbb2dba3f9f881fa5b4Jae Seo // STOPSHIP: Remove the flag when the group volume control implementation completes. 81a4bcfe765789ebef71c36cbb2dba3f9f881fa5b4Jae Seo private static final boolean USE_GROUP = false; 82a4bcfe765789ebef71c36cbb2dba3f9f881fa5b4Jae Seo 83f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah // Time to wait before updating the volume when the user lets go of the seek bar 84f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah // to allow the route provider time to propagate the change and publish a new 85f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah // route descriptor. 86f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah private static final int VOLUME_UPDATE_DELAY_MILLIS = 250; 87f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 8806991009e52024cbb3dde550988e06149e77a269Jae Seo private static final int BUTTON_NEUTRAL_RES_ID = android.R.id.button3; 8906991009e52024cbb3dde550988e06149e77a269Jae Seo private static final int BUTTON_DISCONNECT_RES_ID = android.R.id.button2; 9006991009e52024cbb3dde550988e06149e77a269Jae Seo private static final int BUTTON_STOP_RES_ID = android.R.id.button1; 9106991009e52024cbb3dde550988e06149e77a269Jae Seo 9211417b1cfde8f1749905f2d735623af9214148afJeff Brown private final MediaRouter mRouter; 9311417b1cfde8f1749905f2d735623af9214148afJeff Brown private final MediaRouterCallback mCallback; 9411417b1cfde8f1749905f2d735623af9214148afJeff Brown private final MediaRouter.RouteInfo mRoute; 9511417b1cfde8f1749905f2d735623af9214148afJeff Brown 96eff7719415542ba819054863b0995f07742a7a8aJeff Brown private boolean mCreated; 97e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private boolean mAttachedToWindow; 98e2148398ae5d03c22789aebc3d6359b5ff86c077Jae Seo 99f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo private int mDialogContentWidth; 10011417b1cfde8f1749905f2d735623af9214148afJeff Brown 1017ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim private View mCustomControlView; 10211417b1cfde8f1749905f2d735623af9214148afJeff Brown 10311417b1cfde8f1749905f2d735623af9214148afJeff Brown private Button mDisconnectButton; 10494be6100218126ce6a08bf1f56209578500b361fRoboErik private Button mStopCastingButton; 1051ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private ImageButton mPlayPauseButton; 106b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim private ImageButton mCloseButton; 1071ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private ImageButton mGroupExpandCollapseButton; 10894be6100218126ce6a08bf1f56209578500b361fRoboErik 1091ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private FrameLayout mCustomControlLayout; 1102b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang private FrameLayout mDefaultControlLayout; 11194be6100218126ce6a08bf1f56209578500b361fRoboErik private ImageView mArtView; 1121ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private TextView mTitleView; 1131ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private TextView mSubtitleView; 1147ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim private TextView mRouteNameTextView; 11594be6100218126ce6a08bf1f56209578500b361fRoboErik 116f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah private boolean mVolumeControlEnabled = true; 1172c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Layout for media controllers including play/pause button, volume slider, 1182c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // and group volume sliders. 1198e1281a26eaabd6422fd84c11010134a0a9c3338Jaewan Kim private LinearLayout mMediaControlLayout; 1202c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Layout for media controllers including play/pause button and volume slider. 1212c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim private LinearLayout mMediaMainControlLayout; 1221ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private RelativeLayout mPlaybackControl; 1231ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private LinearLayout mVolumeControl; 1241ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private View mDividerView; 1251ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 1266051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo private ListView mVolumeGroupList; 1271ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private SeekBar mVolumeSlider; 1281ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private boolean mVolumeSliderTouched; 12986a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo private int mVolumeSliderColor; 1302c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim private final int mVolumeGroupListItemHeight; 131f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 13294be6100218126ce6a08bf1f56209578500b361fRoboErik private MediaControllerCompat mMediaController; 13394be6100218126ce6a08bf1f56209578500b361fRoboErik private MediaControllerCallback mControllerCallback; 13494be6100218126ce6a08bf1f56209578500b361fRoboErik private PlaybackStateCompat mState; 13594be6100218126ce6a08bf1f56209578500b361fRoboErik private MediaDescriptionCompat mDescription; 13694be6100218126ce6a08bf1f56209578500b361fRoboErik 137005482649154d0970693b3967241eb4d2cb22003Jaewan Kim private FetchArtTask mFetchArtTask; 1388bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo private Bitmap mArtIconBitmap; 1398bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo private Uri mArtIconUri; 1402b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang private boolean mIsGroupExpanded; 14111417b1cfde8f1749905f2d735623af9214148afJeff Brown 14211417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouteControllerDialog(Context context) { 14311417b1cfde8f1749905f2d735623af9214148afJeff Brown this(context, 0); 14411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 14511417b1cfde8f1749905f2d735623af9214148afJeff Brown 14611417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouteControllerDialog(Context context, int theme) { 14794be6100218126ce6a08bf1f56209578500b361fRoboErik super(MediaRouterThemeHelper.createThemedContext(context), theme); 14811417b1cfde8f1749905f2d735623af9214148afJeff Brown context = getContext(); 14911417b1cfde8f1749905f2d735623af9214148afJeff Brown 15094be6100218126ce6a08bf1f56209578500b361fRoboErik mControllerCallback = new MediaControllerCallback(); 15111417b1cfde8f1749905f2d735623af9214148afJeff Brown mRouter = MediaRouter.getInstance(context); 15211417b1cfde8f1749905f2d735623af9214148afJeff Brown mCallback = new MediaRouterCallback(); 15311417b1cfde8f1749905f2d735623af9214148afJeff Brown mRoute = mRouter.getSelectedRoute(); 154e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik setMediaSession(mRouter.getMediaSessionToken()); 1552c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mVolumeGroupListItemHeight = context.getResources().getDimensionPixelSize( 1562c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim R.dimen.mr_controller_volume_group_list_item_height); 15711417b1cfde8f1749905f2d735623af9214148afJeff Brown } 15811417b1cfde8f1749905f2d735623af9214148afJeff Brown 15911417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 16011417b1cfde8f1749905f2d735623af9214148afJeff Brown * Gets the route that this dialog is controlling. 16111417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 16211417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouter.RouteInfo getRoute() { 16311417b1cfde8f1749905f2d735623af9214148afJeff Brown return mRoute; 16411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 16511417b1cfde8f1749905f2d735623af9214148afJeff Brown 1666051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo private MediaRouter.RouteGroup getGroup() { 1676051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo if (mRoute instanceof MediaRouter.RouteGroup) { 1686051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo return (MediaRouter.RouteGroup) mRoute; 1696051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 1706051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo return null; 1716051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 1726051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 17311417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 17411417b1cfde8f1749905f2d735623af9214148afJeff Brown * Provides the subclass an opportunity to create a view that will 17511417b1cfde8f1749905f2d735623af9214148afJeff Brown * be included within the body of the dialog to offer additional media controls 17611417b1cfde8f1749905f2d735623af9214148afJeff Brown * for the currently playing content. 17711417b1cfde8f1749905f2d735623af9214148afJeff Brown * 17811417b1cfde8f1749905f2d735623af9214148afJeff Brown * @param savedInstanceState The dialog's saved instance state. 17911417b1cfde8f1749905f2d735623af9214148afJeff Brown * @return The media control view, or null if none. 18011417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 18111417b1cfde8f1749905f2d735623af9214148afJeff Brown public View onCreateMediaControlView(Bundle savedInstanceState) { 18211417b1cfde8f1749905f2d735623af9214148afJeff Brown return null; 18311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 18411417b1cfde8f1749905f2d735623af9214148afJeff Brown 18511417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 18611417b1cfde8f1749905f2d735623af9214148afJeff Brown * Gets the media control view that was created by {@link #onCreateMediaControlView(Bundle)}. 18711417b1cfde8f1749905f2d735623af9214148afJeff Brown * 18811417b1cfde8f1749905f2d735623af9214148afJeff Brown * @return The media control view, or null if none. 18911417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 19011417b1cfde8f1749905f2d735623af9214148afJeff Brown public View getMediaControlView() { 1917ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim return mCustomControlView; 19211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 19311417b1cfde8f1749905f2d735623af9214148afJeff Brown 194eff7719415542ba819054863b0995f07742a7a8aJeff Brown /** 195f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * Sets whether to enable the volume slider and volume control using the volume keys 196f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * when the route supports it. 197f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * <p> 198f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * The default value is true. 199f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * </p> 200f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah */ 201f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah public void setVolumeControlEnabled(boolean enable) { 202f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah if (mVolumeControlEnabled != enable) { 203f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah mVolumeControlEnabled = enable; 204f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah if (mCreated) { 2051ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim updateVolumeControl(); 206f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 207f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 208f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 209f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 210f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah /** 211f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * Returns whether to enable the volume slider and volume control using the volume keys 212f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * when the route supports it. 213f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah */ 214f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah public boolean isVolumeControlEnabled() { 215f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah return mVolumeControlEnabled; 216f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 217f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 218f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah /** 21994be6100218126ce6a08bf1f56209578500b361fRoboErik * Set the session to use for metadata and transport controls. The dialog 22094be6100218126ce6a08bf1f56209578500b361fRoboErik * will listen to changes on this session and update the UI automatically in 22194be6100218126ce6a08bf1f56209578500b361fRoboErik * response to changes. 22294be6100218126ce6a08bf1f56209578500b361fRoboErik * 22394be6100218126ce6a08bf1f56209578500b361fRoboErik * @param sessionToken The token for the session to use. 224eff7719415542ba819054863b0995f07742a7a8aJeff Brown */ 225e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private void setMediaSession(MediaSessionCompat.Token sessionToken) { 22694be6100218126ce6a08bf1f56209578500b361fRoboErik if (mMediaController != null) { 22794be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.unregisterCallback(mControllerCallback); 22894be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController = null; 22994be6100218126ce6a08bf1f56209578500b361fRoboErik } 23094be6100218126ce6a08bf1f56209578500b361fRoboErik if (sessionToken == null) { 23194be6100218126ce6a08bf1f56209578500b361fRoboErik return; 23294be6100218126ce6a08bf1f56209578500b361fRoboErik } 233e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (!mAttachedToWindow) { 234e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return; 235e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 23694be6100218126ce6a08bf1f56209578500b361fRoboErik try { 23794be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController = new MediaControllerCompat(getContext(), sessionToken); 23894be6100218126ce6a08bf1f56209578500b361fRoboErik } catch (RemoteException e) { 23994be6100218126ce6a08bf1f56209578500b361fRoboErik Log.e(TAG, "Error creating media controller in setMediaSession.", e); 24094be6100218126ce6a08bf1f56209578500b361fRoboErik } 24194be6100218126ce6a08bf1f56209578500b361fRoboErik if (mMediaController != null) { 24294be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.registerCallback(mControllerCallback); 243eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 24494be6100218126ce6a08bf1f56209578500b361fRoboErik MediaMetadataCompat metadata = mMediaController == null ? null 24594be6100218126ce6a08bf1f56209578500b361fRoboErik : mMediaController.getMetadata(); 24694be6100218126ce6a08bf1f56209578500b361fRoboErik mDescription = metadata == null ? null : metadata.getDescription(); 24794be6100218126ce6a08bf1f56209578500b361fRoboErik mState = mMediaController == null ? null : mMediaController.getPlaybackState(); 24894be6100218126ce6a08bf1f56209578500b361fRoboErik update(); 249eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 250eff7719415542ba819054863b0995f07742a7a8aJeff Brown 251eff7719415542ba819054863b0995f07742a7a8aJeff Brown /** 25294be6100218126ce6a08bf1f56209578500b361fRoboErik * Gets the description being used by the default UI. 25394be6100218126ce6a08bf1f56209578500b361fRoboErik * 25494be6100218126ce6a08bf1f56209578500b361fRoboErik * @return The current description. 255eff7719415542ba819054863b0995f07742a7a8aJeff Brown */ 25694be6100218126ce6a08bf1f56209578500b361fRoboErik public MediaSessionCompat.Token getMediaSession() { 25794be6100218126ce6a08bf1f56209578500b361fRoboErik return mMediaController == null ? null : mMediaController.getSessionToken(); 258eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 259eff7719415542ba819054863b0995f07742a7a8aJeff Brown 26011417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 26111417b1cfde8f1749905f2d735623af9214148afJeff Brown protected void onCreate(Bundle savedInstanceState) { 26211417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onCreate(savedInstanceState); 26311417b1cfde8f1749905f2d735623af9214148afJeff Brown 264a09c7b30d3a5c53281db955eabce171e1aec6feaSungsoo Lim setContentView(R.layout.mr_controller_material_dialog_b); 265f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo 26606991009e52024cbb3dde550988e06149e77a269Jae Seo // Remove the neutral button. 26706991009e52024cbb3dde550988e06149e77a269Jae Seo findViewById(BUTTON_NEUTRAL_RES_ID).setVisibility(View.GONE); 26806991009e52024cbb3dde550988e06149e77a269Jae Seo 26994be6100218126ce6a08bf1f56209578500b361fRoboErik ClickListener listener = new ClickListener(); 270d6748a7926ebb2450337f9f0ff4d445c980344e5Jeff Brown 27106991009e52024cbb3dde550988e06149e77a269Jae Seo mDisconnectButton = (Button) findViewById(BUTTON_DISCONNECT_RES_ID); 27206991009e52024cbb3dde550988e06149e77a269Jae Seo mDisconnectButton.setText(R.string.mr_controller_disconnect); 27394be6100218126ce6a08bf1f56209578500b361fRoboErik mDisconnectButton.setOnClickListener(listener); 27411417b1cfde8f1749905f2d735623af9214148afJeff Brown 27506991009e52024cbb3dde550988e06149e77a269Jae Seo mStopCastingButton = (Button) findViewById(BUTTON_STOP_RES_ID); 27606991009e52024cbb3dde550988e06149e77a269Jae Seo mStopCastingButton.setText(R.string.mr_controller_stop); 27794be6100218126ce6a08bf1f56209578500b361fRoboErik mStopCastingButton.setOnClickListener(listener); 27811417b1cfde8f1749905f2d735623af9214148afJeff Brown 27906991009e52024cbb3dde550988e06149e77a269Jae Seo TypedValue value = new TypedValue(); 28006991009e52024cbb3dde550988e06149e77a269Jae Seo if (getContext().getTheme().resolveAttribute(R.attr.colorPrimary, value, true)) { 28106991009e52024cbb3dde550988e06149e77a269Jae Seo mDisconnectButton.setTextColor(value.data); 28206991009e52024cbb3dde550988e06149e77a269Jae Seo mStopCastingButton.setTextColor(value.data); 28306991009e52024cbb3dde550988e06149e77a269Jae Seo } 28406991009e52024cbb3dde550988e06149e77a269Jae Seo 2851ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mRouteNameTextView = (TextView) findViewById(R.id.mr_name); 2861ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mCloseButton = (ImageButton) findViewById(R.id.mr_close); 287b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim mCloseButton.setOnClickListener(listener); 2881ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mCustomControlLayout = (FrameLayout) findViewById(R.id.mr_custom_control); 2892b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang mDefaultControlLayout = (FrameLayout) findViewById(R.id.mr_default_control); 2907ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim mArtView = (ImageView) findViewById(R.id.mr_art); 2916051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 2928e1281a26eaabd6422fd84c11010134a0a9c3338Jaewan Kim mMediaControlLayout = (LinearLayout) findViewById(R.id.mr_media_control); 2932c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mMediaMainControlLayout = (LinearLayout) findViewById(R.id.mr_media_main_control); 2941ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mDividerView = findViewById(R.id.mr_control_divider); 2951ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 2961ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlaybackControl = (RelativeLayout) findViewById(R.id.mr_playback_control); 2971ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mTitleView = (TextView) findViewById(R.id.mr_control_title); 2981ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mSubtitleView = (TextView) findViewById(R.id.mr_control_subtitle); 2991ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton = (ImageButton) findViewById(R.id.mr_control_play_pause); 3001ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setOnClickListener(listener); 3011ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 3021ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeControl = (LinearLayout) findViewById(R.id.mr_volume_control); 3031ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeSlider = (SeekBar) findViewById(R.id.mr_volume_slider); 3041ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeSlider.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { 3051ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private final Runnable mStopTrackingTouch = new Runnable() { 3061ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim @Override 3071ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim public void run() { 3081ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (mVolumeSliderTouched) { 3091ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeSliderTouched = false; 3101ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim updateVolumeControl(); 3111ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 3121ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 3131ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim }; 3141ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 3151ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim @Override 3161ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim public void onStartTrackingTouch(SeekBar seekBar) { 3171ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (mVolumeSliderTouched) { 3181ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeSlider.removeCallbacks(mStopTrackingTouch); 3191ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 3201ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeSliderTouched = true; 3211ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 3221ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 3231ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 3241ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim @Override 3251ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim public void onStopTrackingTouch(SeekBar seekBar) { 3261ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim // Defer resetting mVolumeSliderTouched to allow the media route provider 3271ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim // a little time to settle into its new state and publish the final 3281ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim // volume update. 3291ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeSlider.postDelayed(mStopTrackingTouch, VOLUME_UPDATE_DELAY_MILLIS); 3301ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 3311ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 3321ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim @Override 3331ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 3341ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (fromUser) { 3351ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mRoute.requestSetVolume(progress); 3361ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 3371ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 3381ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim }); 33986a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo mVolumeSliderColor = MediaRouterThemeHelper.getVolumeSliderColor(getContext()); 3400b0446251d63e184a1bb9ee62ddac0b344e7e571Jae Seo setVolumeSliderColor(getContext(), mVolumeSlider, mVolumeSliderColor); 3411ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 3421ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim TypedArray styledAttributes = getContext().obtainStyledAttributes(new int[] { 3431ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim R.attr.mediaRouteExpandGroupDrawable, 3441ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim R.attr.mediaRouteCollapseGroupDrawable 3451ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim }); 3461ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim final Drawable expandGroupDrawable = styledAttributes.getDrawable(0); 3471ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim final Drawable collapseGroupDrawable = styledAttributes.getDrawable(1); 3481ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim styledAttributes.recycle(); 3491ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 3507ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim mVolumeGroupList = (ListView)findViewById(R.id.mr_volume_group_list); 3511ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mGroupExpandCollapseButton = (ImageButton) findViewById(R.id.mr_group_expand_collapse); 3521ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mGroupExpandCollapseButton.setOnClickListener(new View.OnClickListener() { 3531ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim @Override 3541ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim public void onClick(View v) { 3552b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang mIsGroupExpanded = !mIsGroupExpanded; 3562b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang if (mIsGroupExpanded) { 3571ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mGroupExpandCollapseButton.setImageDrawable(collapseGroupDrawable); 3581ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeGroupList.setVisibility(View.VISIBLE); 3591ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeGroupList.setAdapter( 3601ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim new VolumeGroupAdapter(getContext(), getGroup().getRoutes())); 3611ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 3621ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mGroupExpandCollapseButton.setImageDrawable(expandGroupDrawable); 3631ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeGroupList.setVisibility(View.GONE); 3641ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 3652c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim updateLayoutHeight(); 3661ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 3671ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim }); 36811417b1cfde8f1749905f2d735623af9214148afJeff Brown 3697ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim mCustomControlView = onCreateMediaControlView(savedInstanceState); 3707ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim if (mCustomControlView != null) { 3711ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mCustomControlLayout.addView(mCustomControlView); 3721ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mCustomControlLayout.setVisibility(View.VISIBLE); 3737ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim mArtView.setVisibility(View.GONE); 37411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 37586a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo mCreated = true; 376d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo updateLayout(); 377d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo } 378d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo 379d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo /** 380d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo * Sets the width of the dialog. Also called when configuration changes. 381d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo */ 382d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo void updateLayout() { 383d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo int width = MediaRouteDialogHelper.getDialogWidth(getContext()); 384d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo getWindow().setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT); 385d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo 386d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo View decorView = getWindow().getDecorView(); 387d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo mDialogContentWidth = width - decorView.getPaddingLeft() - decorView.getPaddingRight(); 388d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo 389c74ed2dfd8328da1f1786f1e4fb07f0e8eebd35bJae Seo // Ensure the mArtView is updated. 390c74ed2dfd8328da1f1786f1e4fb07f0e8eebd35bJae Seo mArtIconBitmap = null; 391c74ed2dfd8328da1f1786f1e4fb07f0e8eebd35bJae Seo mArtIconUri = null; 3927ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim update(); 39311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 39411417b1cfde8f1749905f2d735623af9214148afJeff Brown 39511417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 39611417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onAttachedToWindow() { 39711417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onAttachedToWindow(); 398e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mAttachedToWindow = true; 39911417b1cfde8f1749905f2d735623af9214148afJeff Brown 40011417b1cfde8f1749905f2d735623af9214148afJeff Brown mRouter.addCallback(MediaRouteSelector.EMPTY, mCallback, 40111417b1cfde8f1749905f2d735623af9214148afJeff Brown MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS); 402e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik setMediaSession(mRouter.getMediaSessionToken()); 40311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 40411417b1cfde8f1749905f2d735623af9214148afJeff Brown 40511417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 40611417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onDetachedFromWindow() { 40711417b1cfde8f1749905f2d735623af9214148afJeff Brown mRouter.removeCallback(mCallback); 408e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik setMediaSession(null); 409e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mAttachedToWindow = false; 41011417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onDetachedFromWindow(); 41111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 41211417b1cfde8f1749905f2d735623af9214148afJeff Brown 41311417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 41411417b1cfde8f1749905f2d735623af9214148afJeff Brown public boolean onKeyDown(int keyCode, KeyEvent event) { 415ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 416ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 417ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown mRoute.requestUpdateVolume(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ? -1 : 1); 418ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown return true; 41911417b1cfde8f1749905f2d735623af9214148afJeff Brown } 42011417b1cfde8f1749905f2d735623af9214148afJeff Brown return super.onKeyDown(keyCode, event); 42111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 42211417b1cfde8f1749905f2d735623af9214148afJeff Brown 42311417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 42411417b1cfde8f1749905f2d735623af9214148afJeff Brown public boolean onKeyUp(int keyCode, KeyEvent event) { 425ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 426ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 427ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown return true; 42811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 42911417b1cfde8f1749905f2d735623af9214148afJeff Brown return super.onKeyUp(keyCode, event); 43011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 43111417b1cfde8f1749905f2d735623af9214148afJeff Brown 4327ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim private void update() { 43311417b1cfde8f1749905f2d735623af9214148afJeff Brown if (!mRoute.isSelected() || mRoute.isDefault()) { 43411417b1cfde8f1749905f2d735623af9214148afJeff Brown dismiss(); 4357ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim return; 43611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 43794be6100218126ce6a08bf1f56209578500b361fRoboErik if (!mCreated) { 4387ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim return; 43994be6100218126ce6a08bf1f56209578500b361fRoboErik } 4402ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown 4417ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim mRouteNameTextView.setText(mRoute.getName()); 44206991009e52024cbb3dde550988e06149e77a269Jae Seo mDisconnectButton.setVisibility(mRoute.canDisconnect() ? View.VISIBLE : View.GONE); 44394be6100218126ce6a08bf1f56209578500b361fRoboErik 4447ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim if (mCustomControlView == null) { 445005482649154d0970693b3967241eb4d2cb22003Jaewan Kim if (mFetchArtTask != null) { 446005482649154d0970693b3967241eb4d2cb22003Jaewan Kim mFetchArtTask.cancel(true); 44766937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang } 448005482649154d0970693b3967241eb4d2cb22003Jaewan Kim mFetchArtTask = new FetchArtTask(); 449005482649154d0970693b3967241eb4d2cb22003Jaewan Kim mFetchArtTask.execute(); 450f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 4511ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim updateVolumeControl(); 4521ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim updatePlaybackControl(); 4531ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 4541ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 4552c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim private boolean isPlaybackControlAvailable() { 4562c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim return mCustomControlView == null && (mDescription != null || mState != null); 4572c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4582c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 4593fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim /** 4603fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim * Returns the height of main media controller which includes playback control and master 4613fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim * volume control. 4623fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim */ 4632c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim private int getMainControllerHeight(boolean showPlaybackControl) { 4642c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int height = 0; 4652c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (showPlaybackControl || mVolumeControl.getVisibility() == View.VISIBLE) { 4662c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim height += mMediaMainControlLayout.getPaddingTop() 4672c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim + mMediaMainControlLayout.getPaddingBottom(); 4682c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (showPlaybackControl) { 4692c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim height += mPlaybackControl.getMeasuredHeight(); 4702c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4712c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (mVolumeControl.getVisibility() == View.VISIBLE) { 4722c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim height += mVolumeControl.getMeasuredHeight(); 4732c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4742c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (showPlaybackControl && mVolumeControl.getVisibility() == View.VISIBLE) { 4752c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim height += mDividerView.getMeasuredHeight(); 4762c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4772c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4782c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim return height; 4792c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4802c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 4813fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim /** 4823fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim * Updates the height of views and hide artwork or metadata if space is limited. 4833fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim */ 4842c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim private void updateLayoutHeight() { 4852c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (mCustomControlView != null) { 4862c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim return; 4872c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4882c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim View decorView = getWindow().getDecorView(); 4892c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim decorView.measure( 4902c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim MeasureSpec.makeMeasureSpec(getWindow().getAttributes().width, MeasureSpec.EXACTLY), 4912c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim MeasureSpec.UNSPECIFIED); 4922c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int artViewHeight = 0; 4932c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (mArtView.getDrawable() instanceof BitmapDrawable) { 4942c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim Bitmap art = ((BitmapDrawable) mArtView.getDrawable()).getBitmap(); 4952c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (art != null) { 4962c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim artViewHeight = getDesiredArtHeight(art.getWidth(), art.getHeight()); 4972c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mArtView.setScaleType(art.getWidth() >= art.getHeight() 4982c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim ? ImageView.ScaleType.FIT_XY : ImageView.ScaleType.FIT_CENTER); 4992c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5002c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5012c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int mainControllerHeight = getMainControllerHeight(isPlaybackControlAvailable()); 5022c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int volumeGroupListCount = mVolumeGroupList.getVisibility() == View.VISIBLE 5032c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim ? mVolumeGroupList.getAdapter().getCount() : 0; 5042c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int volumeGroupHeight = 0; 5052c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (0 < volumeGroupListCount && volumeGroupListCount <= 2) { 5062c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim volumeGroupHeight = mVolumeGroupListItemHeight * 2; 5072c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } else if (volumeGroupListCount >= 3) { 5082c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim volumeGroupHeight = Math.min(mVolumeGroupListItemHeight * volumeGroupListCount, 5092c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim getContext().getResources().getDimensionPixelSize( 5102c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim R.dimen.mr_controller_volume_group_list_max_height)); 5112c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5128367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim int desiredControlLayoutHeight = 5132c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim Math.max(artViewHeight, volumeGroupHeight) + mainControllerHeight; 5142c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim Rect visibleRect = new Rect(); 5152c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim decorView.getWindowVisibleDisplayFrame(visibleRect); 5162c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Height of non-control views in decor view. 5172c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // This includes title bar, button bar, and dialog's vertical padding which should be 5182c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // always shown. 5192c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int nonControlViewHeight = decorView.getMeasuredHeight() 5202c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim - mDefaultControlLayout.getMeasuredHeight(); 5212c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Maximum allowed height for controls to fit screen. 5222c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int maximumControlViewHeight = visibleRect.height() - nonControlViewHeight; 5232c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 5243fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim // Show artwork if it fits the screen and expanded volume group list has fewer than 3 items. 5253fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim if (artViewHeight > 0 && volumeGroupListCount < 3 5268367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim && desiredControlLayoutHeight <= maximumControlViewHeight) { 5272c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mArtView.setVisibility(View.VISIBLE); 5282c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim setLayoutHeight(mArtView, artViewHeight); 5292c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } else { 5302c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mArtView.setVisibility(View.GONE); 5312c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim artViewHeight = 0; 5328367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim desiredControlLayoutHeight = volumeGroupHeight + mainControllerHeight; 5332c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5342c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Show control if it fits the screen 5352c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (isPlaybackControlAvailable() 5368367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim && desiredControlLayoutHeight <= maximumControlViewHeight) { 5372c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mPlaybackControl.setVisibility(View.VISIBLE); 5382c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } else { 5392c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mPlaybackControl.setVisibility(View.GONE); 5402c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5412c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // TODO: Update the top and bottom padding of the control layout according to the display 5422c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // height. 5432c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mDividerView.setVisibility((mVolumeControl.getVisibility() == View.VISIBLE 5442c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim && mPlaybackControl.getVisibility() == View.VISIBLE) 5452c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim ? View.VISIBLE : View.GONE); 5462c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mMediaControlLayout.setVisibility((mVolumeControl.getVisibility() == View.GONE 5472c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim && mPlaybackControl.getVisibility() == View.GONE) 5482c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim ? View.GONE : View.VISIBLE); 5492c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mainControllerHeight = getMainControllerHeight( 5502c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mPlaybackControl.getVisibility() == View.VISIBLE); 5518367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim desiredControlLayoutHeight = 5522c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim Math.max(artViewHeight, volumeGroupHeight) + mainControllerHeight; 5532c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 5542c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Limit the volume group list height to fit the screen. 5558367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim if (desiredControlLayoutHeight > maximumControlViewHeight) { 5568367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim volumeGroupHeight -= (desiredControlLayoutHeight - maximumControlViewHeight); 5578367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim desiredControlLayoutHeight = maximumControlViewHeight; 5582c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5592c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim setLayoutHeight(mVolumeGroupList, volumeGroupHeight); 5608367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim setLayoutHeight(mDefaultControlLayout, desiredControlLayoutHeight); 5612c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5622c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 5631ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private void updateVolumeControl() { 5641ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (!mVolumeSliderTouched) { 5651ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (isVolumeControlAvailable()) { 5661ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeControl.setVisibility(View.VISIBLE); 5671ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeSlider.setMax(mRoute.getVolumeMax()); 5681ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeSlider.setProgress(mRoute.getVolume()); 5691ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (USE_GROUP) { 5701ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (getGroup() == null) { 5711ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mGroupExpandCollapseButton.setVisibility(View.GONE); 5721ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 5731ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mGroupExpandCollapseButton.setVisibility(View.VISIBLE); 5741ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim VolumeGroupAdapter adapter = 5751ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim (VolumeGroupAdapter) mVolumeGroupList.getAdapter(); 5761ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (adapter != null) { 5771ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim adapter.notifyDataSetChanged(); 5781ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 5791ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 5801ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 5811ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 5821ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeControl.setVisibility(View.GONE); 5831ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 5842c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim updateLayoutHeight(); 5851ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 5861ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 5871ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 5881ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private void updatePlaybackControl() { 5892c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (isPlaybackControlAvailable()) { 5901ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlaybackControl.setVisibility(View.VISIBLE); 5911ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim CharSequence title = mDescription == null ? null : mDescription.getTitle(); 5921ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean hasTitle = !TextUtils.isEmpty(title); 5931ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 5941ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim CharSequence subtitle = mDescription == null ? null : mDescription.getSubtitle(); 5951ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean hasSubtitle = !TextUtils.isEmpty(subtitle); 5961ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 5971ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (!hasTitle && !hasSubtitle) { 5981ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (mRoute.getPresentationDisplayId() 5991ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim != MediaRouter.RouteInfo.PRESENTATION_DISPLAY_ID_NONE) { 6001ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim // The user is currently casting screen. 6011ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mTitleView.setText(R.string.mr_controller_casting_screen); 6021ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 6031ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mTitleView.setText((mState == null 6041ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim || mState.getState() == PlaybackStateCompat.STATE_NONE) 6051ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim ? R.string.mr_controller_no_media_selected 6061ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim : R.string.mr_controller_no_info_available); 6071ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 6081ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mTitleView.setVisibility(View.VISIBLE); 6091ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mSubtitleView.setVisibility(View.GONE); 6101ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 6111ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mTitleView.setText(title); 6121ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mTitleView.setVisibility(hasTitle ? View.VISIBLE : View.GONE); 6131ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mSubtitleView.setText(subtitle); 6141ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mSubtitleView.setVisibility(hasSubtitle ? View.VISIBLE : View.GONE); 6151ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 6161ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (mState != null) { 6171ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean isPlaying = mState.getState() == PlaybackStateCompat.STATE_BUFFERING 6181ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim || mState.getState() == PlaybackStateCompat.STATE_PLAYING; 6191ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean supportsPlay = (mState.getActions() & (PlaybackStateCompat.ACTION_PLAY 6201ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0; 6211ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean supportsPause = (mState.getActions() & (PlaybackStateCompat.ACTION_PAUSE 6221ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0; 6231ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (isPlaying && supportsPause) { 6241ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setVisibility(View.VISIBLE); 6251ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setImageResource(MediaRouterThemeHelper.getThemeResource( 6261ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim getContext(), R.attr.mediaRoutePauseDrawable)); 6271ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setContentDescription(getContext().getResources() 6281ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim .getText(R.string.mr_controller_pause)); 6291ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else if (!isPlaying && supportsPlay) { 6301ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setVisibility(View.VISIBLE); 6311ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setImageResource(MediaRouterThemeHelper.getThemeResource( 6321ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim getContext(), R.attr.mediaRoutePlayDrawable)); 6331ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setContentDescription(getContext().getResources() 6341ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim .getText(R.string.mr_controller_play)); 6351ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 6361ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setVisibility(View.GONE); 6371ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 6381ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 6391ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 6401ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlaybackControl.setVisibility(View.GONE); 6411ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 6422c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim updateLayoutHeight(); 6432b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang } 6442b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang 645f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah private boolean isVolumeControlAvailable() { 646f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah return mVolumeControlEnabled && mRoute.getVolumeHandling() == 647f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE; 648f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 649f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 650be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang private static void setLayoutHeight(View view, int height) { 651be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang ViewGroup.LayoutParams lp = view.getLayoutParams(); 652be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang lp.height = height; 653be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang view.setLayoutParams(lp); 654be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang } 655be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang 6560b0446251d63e184a1bb9ee62ddac0b344e7e571Jae Seo private static void setVolumeSliderColor(Context context, SeekBar volumeSlider, int color) { 65786a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo volumeSlider.getProgressDrawable().setColorFilter(color, PorterDuff.Mode.SRC_IN); 65886a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo if (Build.VERSION.SDK_INT >= 16) { 65986a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo SeekBarJellybean.getThumb(volumeSlider).setColorFilter(color, PorterDuff.Mode.SRC_IN); 6600b0446251d63e184a1bb9ee62ddac0b344e7e571Jae Seo } else { 6610b0446251d63e184a1bb9ee62ddac0b344e7e571Jae Seo // In case getThumb() isn't available, use the thumb drawable from AppCompat. 6620b0446251d63e184a1bb9ee62ddac0b344e7e571Jae Seo Drawable thumb = 6630b0446251d63e184a1bb9ee62ddac0b344e7e571Jae Seo context.getResources().getDrawable(R.drawable.abc_seekbar_thumb_material); 6640b0446251d63e184a1bb9ee62ddac0b344e7e571Jae Seo thumb.setColorFilter(color, PorterDuff.Mode.SRC_IN); 6650b0446251d63e184a1bb9ee62ddac0b344e7e571Jae Seo volumeSlider.setThumb(thumb); 66686a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo } 66786a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo } 66886a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo 66913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim /** 67013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim * Returns desired art height to fit into controller dialog. 67113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim */ 67213d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim private int getDesiredArtHeight(int originalWidth, int originalHeight) { 67313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim if (originalWidth >= originalHeight) { 67413d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // For landscape art, fit width to dialog width. 675f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo return (int) ((float) mDialogContentWidth * originalHeight / originalWidth + 0.5f); 67613d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim } 67713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // For portrait art, fit height to 16:9 ratio case's height. 678f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo return (int) ((float) mDialogContentWidth * 9 / 16 + 0.5f); 67913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim } 68013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim 68111417b1cfde8f1749905f2d735623af9214148afJeff Brown private final class MediaRouterCallback extends MediaRouter.Callback { 68211417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 68311417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route) { 68411417b1cfde8f1749905f2d735623af9214148afJeff Brown update(); 68511417b1cfde8f1749905f2d735623af9214148afJeff Brown } 68611417b1cfde8f1749905f2d735623af9214148afJeff Brown 68711417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 68811417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo route) { 68911417b1cfde8f1749905f2d735623af9214148afJeff Brown update(); 69011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 69111417b1cfde8f1749905f2d735623af9214148afJeff Brown 69211417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 69311417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteVolumeChanged(MediaRouter router, MediaRouter.RouteInfo route) { 69411417b1cfde8f1749905f2d735623af9214148afJeff Brown if (route == mRoute) { 6951ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim updateVolumeControl(); 69694be6100218126ce6a08bf1f56209578500b361fRoboErik } 69794be6100218126ce6a08bf1f56209578500b361fRoboErik } 69894be6100218126ce6a08bf1f56209578500b361fRoboErik } 69994be6100218126ce6a08bf1f56209578500b361fRoboErik 70094be6100218126ce6a08bf1f56209578500b361fRoboErik private final class MediaControllerCallback extends MediaControllerCompat.Callback { 70194be6100218126ce6a08bf1f56209578500b361fRoboErik @Override 70294be6100218126ce6a08bf1f56209578500b361fRoboErik public void onSessionDestroyed() { 70394be6100218126ce6a08bf1f56209578500b361fRoboErik if (mMediaController != null) { 70494be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.unregisterCallback(mControllerCallback); 70594be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController = null; 70694be6100218126ce6a08bf1f56209578500b361fRoboErik } 70794be6100218126ce6a08bf1f56209578500b361fRoboErik } 70894be6100218126ce6a08bf1f56209578500b361fRoboErik 70994be6100218126ce6a08bf1f56209578500b361fRoboErik @Override 71094be6100218126ce6a08bf1f56209578500b361fRoboErik public void onPlaybackStateChanged(PlaybackStateCompat state) { 71194be6100218126ce6a08bf1f56209578500b361fRoboErik mState = state; 71294be6100218126ce6a08bf1f56209578500b361fRoboErik update(); 71394be6100218126ce6a08bf1f56209578500b361fRoboErik } 71494be6100218126ce6a08bf1f56209578500b361fRoboErik 71594be6100218126ce6a08bf1f56209578500b361fRoboErik @Override 71694be6100218126ce6a08bf1f56209578500b361fRoboErik public void onMetadataChanged(MediaMetadataCompat metadata) { 71794be6100218126ce6a08bf1f56209578500b361fRoboErik mDescription = metadata == null ? null : metadata.getDescription(); 71894be6100218126ce6a08bf1f56209578500b361fRoboErik update(); 71994be6100218126ce6a08bf1f56209578500b361fRoboErik } 72094be6100218126ce6a08bf1f56209578500b361fRoboErik } 72194be6100218126ce6a08bf1f56209578500b361fRoboErik 72294be6100218126ce6a08bf1f56209578500b361fRoboErik private final class ClickListener implements View.OnClickListener { 72394be6100218126ce6a08bf1f56209578500b361fRoboErik @Override 72494be6100218126ce6a08bf1f56209578500b361fRoboErik public void onClick(View v) { 72594be6100218126ce6a08bf1f56209578500b361fRoboErik int id = v.getId(); 72606991009e52024cbb3dde550988e06149e77a269Jae Seo if (id == BUTTON_STOP_RES_ID || id == BUTTON_DISCONNECT_RES_ID) { 72794be6100218126ce6a08bf1f56209578500b361fRoboErik if (mRoute.isSelected()) { 72806991009e52024cbb3dde550988e06149e77a269Jae Seo mRouter.unselect(id == BUTTON_STOP_RES_ID ? 72994be6100218126ce6a08bf1f56209578500b361fRoboErik MediaRouter.UNSELECT_REASON_STOPPED : 73094be6100218126ce6a08bf1f56209578500b361fRoboErik MediaRouter.UNSELECT_REASON_DISCONNECTED); 73194be6100218126ce6a08bf1f56209578500b361fRoboErik } 73294be6100218126ce6a08bf1f56209578500b361fRoboErik dismiss(); 7337ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim } else if (id == R.id.mr_control_play_pause) { 73494be6100218126ce6a08bf1f56209578500b361fRoboErik if (mMediaController != null && mState != null) { 73594be6100218126ce6a08bf1f56209578500b361fRoboErik if (mState.getState() == PlaybackStateCompat.STATE_PLAYING) { 73694be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.getTransportControls().pause(); 73794be6100218126ce6a08bf1f56209578500b361fRoboErik } else { 73894be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.getTransportControls().play(); 73994be6100218126ce6a08bf1f56209578500b361fRoboErik } 74094be6100218126ce6a08bf1f56209578500b361fRoboErik } 7411ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else if (id == R.id.mr_close) { 742b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim dismiss(); 74311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 74411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 74511417b1cfde8f1749905f2d735623af9214148afJeff Brown } 746005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 7476051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo private class VolumeGroupAdapter extends ArrayAdapter<MediaRouter.RouteInfo> { 7480e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo final static float DISABLED_ALPHA = .3f; 7490e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo 7506051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo final OnSeekBarChangeListener mOnSeekBarChangeListener = new OnSeekBarChangeListener() { 7516051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo @Override 7526051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 7536051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo if (fromUser) { 7546051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo int position = (int) seekBar.getTag(); 7556051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo getGroup().getRouteAt(position).requestSetVolume(progress); 7566051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 7576051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 7586051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 7596051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo @Override 7606051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo public void onStartTrackingTouch(SeekBar seekBar) { 7616051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo // TODO: Implement 7626051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 7636051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 7646051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo @Override 7656051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo public void onStopTrackingTouch(SeekBar seekBar) { 7666051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo // TODO: Implement 7676051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 7686051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo }; 7696051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 7706051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo public VolumeGroupAdapter(Context context, List<MediaRouter.RouteInfo> objects) { 7716051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo super(context, 0, objects); 7726051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 7736051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 7746051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo @Override 7756051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo public View getView(final int position, View convertView, ViewGroup parent) { 7766051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo View v = convertView; 7776051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo if (v == null) { 7786051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo v = LayoutInflater.from(getContext()).inflate( 7792c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim R.layout.mr_controller_volume_item, parent, false); 7800b0446251d63e184a1bb9ee62ddac0b344e7e571Jae Seo setVolumeSliderColor(getContext(), (SeekBar) v.findViewById(R.id.mr_volume_slider), 7810b0446251d63e184a1bb9ee62ddac0b344e7e571Jae Seo mVolumeSliderColor); 7826051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 7836051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo MediaRouter.RouteInfo route = getItem(position); 7846051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo if (route != null) { 7850e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo boolean isEnabled = route.isEnabled(); 7860e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo 7877ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim TextView routeName = (TextView) v.findViewById(R.id.mr_name); 7880e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo routeName.setEnabled(isEnabled); 7890e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo routeName.setText(route.getName()); 7906051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 7917ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim SeekBar volumeSlider = (SeekBar) v.findViewById(R.id.mr_volume_slider); 7920e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setEnabled(isEnabled); 7936051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo volumeSlider.setTag(position); 7940e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo if (isEnabled) { 7950e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo if (route.getVolumeHandling() 7960e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo == MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE) { 7970e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setMax(route.getVolumeMax()); 7980e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setProgress(route.getVolume()); 7990e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setOnSeekBarChangeListener(mOnSeekBarChangeListener); 8000e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo } else { 8010e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setMax(100); 8020e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setProgress(100); 8030e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setEnabled(false); 8040e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo } 8050e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo } 806418c688351713e9349227262163eef752a8e7ce6Jae Seo if (Build.VERSION.SDK_INT >= 16) { 807418c688351713e9349227262163eef752a8e7ce6Jae Seo SeekBarJellybean.getThumb(volumeSlider).mutate().setAlpha(isEnabled ? 255 : 0); 808418c688351713e9349227262163eef752a8e7ce6Jae Seo // TODO: Still see an artifact even though the thumb is transparent. Remove it. 809418c688351713e9349227262163eef752a8e7ce6Jae Seo } 8100e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo 8110e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo ImageView volumeItemIcon = 8127ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim (ImageView) v.findViewById(R.id.mr_volume_item_icon); 81377367b4a1871417198d0399d9ad074314c758567Jae Seo volumeItemIcon.setAlpha(isEnabled ? 255 : (int) (255 * DISABLED_ALPHA)); 8146051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 8156051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo return v; 8166051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 8176051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 8186051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 819005482649154d0970693b3967241eb4d2cb22003Jaewan Kim private class FetchArtTask extends AsyncTask<Void, Void, Bitmap> { 8208bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo final Bitmap mIconBitmap; 8218bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo final Uri mIconUri; 8228bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo int mBackgroundColor; 8238bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo 8248bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo FetchArtTask() { 8258bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mIconBitmap = mDescription == null ? null : mDescription.getIconBitmap(); 8268bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mIconUri = mDescription == null ? null : mDescription.getIconUri(); 8278bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } 8288bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo 8298bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo @Override 8308bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo protected void onPreExecute() { 8318bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo if (mArtIconBitmap == mIconBitmap && mArtIconUri == mIconUri) { 8328bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo // Already handled the current art. 8338bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo cancel(true); 8348bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } 8358bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } 836005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 837005482649154d0970693b3967241eb4d2cb22003Jaewan Kim @Override 838005482649154d0970693b3967241eb4d2cb22003Jaewan Kim protected Bitmap doInBackground(Void... arg) { 83913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim Bitmap art = null; 8408bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo if (mIconBitmap != null) { 8418bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo art = mIconBitmap; 8428bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } else if (mIconUri != null) { 8438bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo String scheme = mIconUri.getScheme(); 844005482649154d0970693b3967241eb4d2cb22003Jaewan Kim if (!(ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme) 845005482649154d0970693b3967241eb4d2cb22003Jaewan Kim || ContentResolver.SCHEME_CONTENT.equals(scheme) 846005482649154d0970693b3967241eb4d2cb22003Jaewan Kim || ContentResolver.SCHEME_FILE.equals(scheme))) { 847005482649154d0970693b3967241eb4d2cb22003Jaewan Kim Log.w(TAG, "Icon Uri should point to local resources."); 848005482649154d0970693b3967241eb4d2cb22003Jaewan Kim return null; 849005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 850005482649154d0970693b3967241eb4d2cb22003Jaewan Kim BufferedInputStream stream = null; 851005482649154d0970693b3967241eb4d2cb22003Jaewan Kim try { 852005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream = new BufferedInputStream( 8538bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo getContext().getContentResolver().openInputStream(mIconUri)); 854005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 85513d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // Query art size. 856005482649154d0970693b3967241eb4d2cb22003Jaewan Kim BitmapFactory.Options options = new BitmapFactory.Options(); 857005482649154d0970693b3967241eb4d2cb22003Jaewan Kim options.inJustDecodeBounds = true; 858005482649154d0970693b3967241eb4d2cb22003Jaewan Kim BitmapFactory.decodeStream(stream, null, options); 85913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim if (options.outWidth == 0 || options.outHeight == 0) { 86013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim return null; 86113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim } 86213d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // Rewind the stream in order to restart art decoding. 863005482649154d0970693b3967241eb4d2cb22003Jaewan Kim try { 864005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream.reset(); 865005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } catch (IOException e) { 866005482649154d0970693b3967241eb4d2cb22003Jaewan Kim // Failed to rewind the stream, try to reopen it. 867005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream.close(); 868005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream = new BufferedInputStream(getContext().getContentResolver() 8698bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo .openInputStream(mIconUri)); 870005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 87113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // Calculate required size to decode the art and possibly resize it. 872005482649154d0970693b3967241eb4d2cb22003Jaewan Kim options.inJustDecodeBounds = false; 87313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim int reqHeight = getDesiredArtHeight(options.outWidth, options.outHeight); 87413d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim int ratio = options.outHeight / reqHeight; 875005482649154d0970693b3967241eb4d2cb22003Jaewan Kim options.inSampleSize = Math.max(1, Integer.highestOneBit(ratio)); 876005482649154d0970693b3967241eb4d2cb22003Jaewan Kim if (isCancelled()) { 877005482649154d0970693b3967241eb4d2cb22003Jaewan Kim return null; 878005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 87913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim art = BitmapFactory.decodeStream(stream, null, options); 880005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } catch (IOException e){ 8818bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo Log.w(TAG, "Unable to open: " + mIconUri, e); 882005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } finally { 883005482649154d0970693b3967241eb4d2cb22003Jaewan Kim if (stream != null) { 884005482649154d0970693b3967241eb4d2cb22003Jaewan Kim try { 885005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream.close(); 886005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } catch (IOException e) { 887005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 888005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 889005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 890005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 891145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim if (art != null && art.getWidth() < art.getHeight()) { 892145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim // Portrait art requires background color. 893145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim Palette palette = new Palette.Builder(art).maximumColorCount(1).generate(); 894be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang mBackgroundColor = palette.getSwatches().isEmpty() 895145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim ? 0 : palette.getSwatches().get(0).getRgb(); 896005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 89713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim return art; 898005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 899005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 900005482649154d0970693b3967241eb4d2cb22003Jaewan Kim @Override 901005482649154d0970693b3967241eb4d2cb22003Jaewan Kim protected void onCancelled() { 902005482649154d0970693b3967241eb4d2cb22003Jaewan Kim mFetchArtTask = null; 903005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 904005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 905005482649154d0970693b3967241eb4d2cb22003Jaewan Kim @Override 90613d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim protected void onPostExecute(Bitmap art) { 907005482649154d0970693b3967241eb4d2cb22003Jaewan Kim mFetchArtTask = null; 9088bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo if (mArtIconBitmap != mIconBitmap || mArtIconUri != mIconUri) { 9098bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mArtIconBitmap = mIconBitmap; 9108bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mArtIconUri = mIconUri; 9118bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo 9128bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mArtView.setImageBitmap(art); 9138bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mArtView.setBackgroundColor(mBackgroundColor); 9142c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim updateLayoutHeight(); 9158bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } 916005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 917005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 9186051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo} 919