MediaRouteControllerDialog.java revision 7447b1958129579090ee279caac7d703dba2ad28
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; 23c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kimimport android.content.res.Resources; 246051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.content.res.TypedArray; 25005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.graphics.Bitmap; 26005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.graphics.BitmapFactory; 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; 3211417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.os.Bundle; 3394be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.os.RemoteException; 3494be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.MediaDescriptionCompat; 3594be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.MediaMetadataCompat; 3694be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.MediaControllerCompat; 3794be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.MediaSessionCompat; 3894be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.PlaybackStateCompat; 39005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.support.v7.graphics.Palette; 4011417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouteSelector; 4111417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouter; 4211417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.mediarouter.R; 4394be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.text.TextUtils; 4494be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.util.Log; 4506991009e52024cbb3dde550988e06149e77a269Jae Seoimport android.util.TypedValue; 4611417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.KeyEvent; 476051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.view.LayoutInflater; 4811417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.View; 4940dd800ece983a94ea6a26a27481da50f489e7c8Jaewan Kimimport android.view.View.MeasureSpec; 506051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.view.ViewGroup; 5186dcb627078ea297c4337ed634fc3fe874e23897Jae Seoimport android.view.ViewTreeObserver; 526051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.widget.ArrayAdapter; 5311417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.Button; 5411417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.widget.FrameLayout; 5594be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.ImageButton; 5694be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.ImageView; 57f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shahimport android.widget.LinearLayout; 586051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.widget.ListView; 597ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Limimport android.widget.RelativeLayout; 60f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shahimport android.widget.SeekBar; 6194be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.widget.TextView; 6211417b1cfde8f1749905f2d735623af9214148afJeff Brown 63005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport java.io.BufferedInputStream; 64005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport java.io.IOException; 656051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport java.util.List; 66005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 6711417b1cfde8f1749905f2d735623af9214148afJeff Brown/** 6811417b1cfde8f1749905f2d735623af9214148afJeff Brown * This class implements the route controller dialog for {@link MediaRouter}. 6911417b1cfde8f1749905f2d735623af9214148afJeff Brown * <p> 7011417b1cfde8f1749905f2d735623af9214148afJeff Brown * This dialog allows the user to control or disconnect from the currently selected route. 7111417b1cfde8f1749905f2d735623af9214148afJeff Brown * </p> 7211417b1cfde8f1749905f2d735623af9214148afJeff Brown * 7311417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see MediaRouteButton 7411417b1cfde8f1749905f2d735623af9214148afJeff Brown * @see MediaRouteActionProvider 7511417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 7689530d511efd566d53bedd9178454dd01d227c61Jae Seopublic class MediaRouteControllerDialog extends AlertDialog { 7711417b1cfde8f1749905f2d735623af9214148afJeff Brown private static final String TAG = "MediaRouteControllerDialog"; 7811417b1cfde8f1749905f2d735623af9214148afJeff Brown 79a4bcfe765789ebef71c36cbb2dba3f9f881fa5b4Jae Seo // STOPSHIP: Remove the flag when the group volume control implementation completes. 80a4bcfe765789ebef71c36cbb2dba3f9f881fa5b4Jae Seo private static final boolean USE_GROUP = false; 81a4bcfe765789ebef71c36cbb2dba3f9f881fa5b4Jae Seo 82f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah // Time to wait before updating the volume when the user lets go of the seek bar 83f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah // to allow the route provider time to propagate the change and publish a new 84f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah // route descriptor. 85f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah private static final int VOLUME_UPDATE_DELAY_MILLIS = 250; 86435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim private static final int VOLUME_SLIDER_TAG_MASTER = 0; 87435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim private static final int VOLUME_SLIDER_TAG_BASE = 100; 88f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 8906991009e52024cbb3dde550988e06149e77a269Jae Seo private static final int BUTTON_NEUTRAL_RES_ID = android.R.id.button3; 9006991009e52024cbb3dde550988e06149e77a269Jae Seo private static final int BUTTON_DISCONNECT_RES_ID = android.R.id.button2; 9106991009e52024cbb3dde550988e06149e77a269Jae Seo private static final int BUTTON_STOP_RES_ID = android.R.id.button1; 9206991009e52024cbb3dde550988e06149e77a269Jae Seo 9311417b1cfde8f1749905f2d735623af9214148afJeff Brown private final MediaRouter mRouter; 9411417b1cfde8f1749905f2d735623af9214148afJeff Brown private final MediaRouterCallback mCallback; 9511417b1cfde8f1749905f2d735623af9214148afJeff Brown private final MediaRouter.RouteInfo mRoute; 9611417b1cfde8f1749905f2d735623af9214148afJeff Brown 97eff7719415542ba819054863b0995f07742a7a8aJeff Brown private boolean mCreated; 98e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private boolean mAttachedToWindow; 99e2148398ae5d03c22789aebc3d6359b5ff86c077Jae Seo 100f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo private int mDialogContentWidth; 10111417b1cfde8f1749905f2d735623af9214148afJeff Brown 1027ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim private View mCustomControlView; 10311417b1cfde8f1749905f2d735623af9214148afJeff Brown 10411417b1cfde8f1749905f2d735623af9214148afJeff Brown private Button mDisconnectButton; 10594be6100218126ce6a08bf1f56209578500b361fRoboErik private Button mStopCastingButton; 1061ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private ImageButton mPlayPauseButton; 107b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim private ImageButton mCloseButton; 1081ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private ImageButton mGroupExpandCollapseButton; 10994be6100218126ce6a08bf1f56209578500b361fRoboErik 1101ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private FrameLayout mCustomControlLayout; 1112b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang private FrameLayout mDefaultControlLayout; 11294be6100218126ce6a08bf1f56209578500b361fRoboErik private ImageView mArtView; 1131ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private TextView mTitleView; 1141ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private TextView mSubtitleView; 1157ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim private TextView mRouteNameTextView; 11694be6100218126ce6a08bf1f56209578500b361fRoboErik 117f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah private boolean mVolumeControlEnabled = true; 1182c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Layout for media controllers including play/pause button, volume slider, 1192c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // and group volume sliders. 1208e1281a26eaabd6422fd84c11010134a0a9c3338Jaewan Kim private LinearLayout mMediaControlLayout; 1212c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Layout for media controllers including play/pause button and volume slider. 1222c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim private LinearLayout mMediaMainControlLayout; 1231ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private RelativeLayout mPlaybackControl; 1241ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private LinearLayout mVolumeControl; 1251ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private View mDividerView; 1261ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 1276051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo private ListView mVolumeGroupList; 1281ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private SeekBar mVolumeSlider; 129435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim private VolumeChangeListener mVolumeChangeListener; 1301ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private boolean mVolumeSliderTouched; 131c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim private int mVolumeGroupListItemIconSize; 132c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim private int mVolumeGroupListItemHeight; 133c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim private int mVolumeGroupListMaxHeight; 134c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim private final int mVolumeGroupListPaddingTop; 135f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 13694be6100218126ce6a08bf1f56209578500b361fRoboErik private MediaControllerCompat mMediaController; 13794be6100218126ce6a08bf1f56209578500b361fRoboErik private MediaControllerCallback mControllerCallback; 13894be6100218126ce6a08bf1f56209578500b361fRoboErik private PlaybackStateCompat mState; 13994be6100218126ce6a08bf1f56209578500b361fRoboErik private MediaDescriptionCompat mDescription; 14094be6100218126ce6a08bf1f56209578500b361fRoboErik 141005482649154d0970693b3967241eb4d2cb22003Jaewan Kim private FetchArtTask mFetchArtTask; 1428bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo private Bitmap mArtIconBitmap; 1438bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo private Uri mArtIconUri; 1442b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang private boolean mIsGroupExpanded; 14511417b1cfde8f1749905f2d735623af9214148afJeff Brown 14611417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouteControllerDialog(Context context) { 14711417b1cfde8f1749905f2d735623af9214148afJeff Brown this(context, 0); 14811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 14911417b1cfde8f1749905f2d735623af9214148afJeff Brown 15011417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouteControllerDialog(Context context, int theme) { 15194be6100218126ce6a08bf1f56209578500b361fRoboErik super(MediaRouterThemeHelper.createThemedContext(context), theme); 15211417b1cfde8f1749905f2d735623af9214148afJeff Brown context = getContext(); 15311417b1cfde8f1749905f2d735623af9214148afJeff Brown 15494be6100218126ce6a08bf1f56209578500b361fRoboErik mControllerCallback = new MediaControllerCallback(); 15511417b1cfde8f1749905f2d735623af9214148afJeff Brown mRouter = MediaRouter.getInstance(context); 15611417b1cfde8f1749905f2d735623af9214148afJeff Brown mCallback = new MediaRouterCallback(); 15711417b1cfde8f1749905f2d735623af9214148afJeff Brown mRoute = mRouter.getSelectedRoute(); 158e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik setMediaSession(mRouter.getMediaSessionToken()); 159c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim mVolumeGroupListPaddingTop = context.getResources().getDimensionPixelSize( 160c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim R.dimen.mr_controller_volume_group_list_padding_top); 16111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 16211417b1cfde8f1749905f2d735623af9214148afJeff Brown 16311417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 16411417b1cfde8f1749905f2d735623af9214148afJeff Brown * Gets the route that this dialog is controlling. 16511417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 16611417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouter.RouteInfo getRoute() { 16711417b1cfde8f1749905f2d735623af9214148afJeff Brown return mRoute; 16811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 16911417b1cfde8f1749905f2d735623af9214148afJeff Brown 1706051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo private MediaRouter.RouteGroup getGroup() { 1716051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo if (mRoute instanceof MediaRouter.RouteGroup) { 1726051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo return (MediaRouter.RouteGroup) mRoute; 1736051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 1746051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo return null; 1756051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 1766051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 17711417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 17811417b1cfde8f1749905f2d735623af9214148afJeff Brown * Provides the subclass an opportunity to create a view that will 17911417b1cfde8f1749905f2d735623af9214148afJeff Brown * be included within the body of the dialog to offer additional media controls 18011417b1cfde8f1749905f2d735623af9214148afJeff Brown * for the currently playing content. 18111417b1cfde8f1749905f2d735623af9214148afJeff Brown * 18211417b1cfde8f1749905f2d735623af9214148afJeff Brown * @param savedInstanceState The dialog's saved instance state. 18311417b1cfde8f1749905f2d735623af9214148afJeff Brown * @return The media control view, or null if none. 18411417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 18511417b1cfde8f1749905f2d735623af9214148afJeff Brown public View onCreateMediaControlView(Bundle savedInstanceState) { 18611417b1cfde8f1749905f2d735623af9214148afJeff Brown return null; 18711417b1cfde8f1749905f2d735623af9214148afJeff Brown } 18811417b1cfde8f1749905f2d735623af9214148afJeff Brown 18911417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 19011417b1cfde8f1749905f2d735623af9214148afJeff Brown * Gets the media control view that was created by {@link #onCreateMediaControlView(Bundle)}. 19111417b1cfde8f1749905f2d735623af9214148afJeff Brown * 19211417b1cfde8f1749905f2d735623af9214148afJeff Brown * @return The media control view, or null if none. 19311417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 19411417b1cfde8f1749905f2d735623af9214148afJeff Brown public View getMediaControlView() { 1957ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim return mCustomControlView; 19611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 19711417b1cfde8f1749905f2d735623af9214148afJeff Brown 198eff7719415542ba819054863b0995f07742a7a8aJeff Brown /** 199f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * Sets whether to enable the volume slider and volume control using the volume keys 200f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * when the route supports it. 201f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * <p> 202f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * The default value is true. 203f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * </p> 204f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah */ 205f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah public void setVolumeControlEnabled(boolean enable) { 206f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah if (mVolumeControlEnabled != enable) { 207f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah mVolumeControlEnabled = enable; 208f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah if (mCreated) { 2091ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim updateVolumeControl(); 210f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 211f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 212f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 213f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 214f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah /** 215f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * Returns whether to enable the volume slider and volume control using the volume keys 216f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * when the route supports it. 217f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah */ 218f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah public boolean isVolumeControlEnabled() { 219f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah return mVolumeControlEnabled; 220f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 221f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 222f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah /** 22394be6100218126ce6a08bf1f56209578500b361fRoboErik * Set the session to use for metadata and transport controls. The dialog 22494be6100218126ce6a08bf1f56209578500b361fRoboErik * will listen to changes on this session and update the UI automatically in 22594be6100218126ce6a08bf1f56209578500b361fRoboErik * response to changes. 22694be6100218126ce6a08bf1f56209578500b361fRoboErik * 22794be6100218126ce6a08bf1f56209578500b361fRoboErik * @param sessionToken The token for the session to use. 228eff7719415542ba819054863b0995f07742a7a8aJeff Brown */ 229e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private void setMediaSession(MediaSessionCompat.Token sessionToken) { 23094be6100218126ce6a08bf1f56209578500b361fRoboErik if (mMediaController != null) { 23194be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.unregisterCallback(mControllerCallback); 23294be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController = null; 23394be6100218126ce6a08bf1f56209578500b361fRoboErik } 23494be6100218126ce6a08bf1f56209578500b361fRoboErik if (sessionToken == null) { 23594be6100218126ce6a08bf1f56209578500b361fRoboErik return; 23694be6100218126ce6a08bf1f56209578500b361fRoboErik } 237e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (!mAttachedToWindow) { 238e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return; 239e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 24094be6100218126ce6a08bf1f56209578500b361fRoboErik try { 24194be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController = new MediaControllerCompat(getContext(), sessionToken); 24294be6100218126ce6a08bf1f56209578500b361fRoboErik } catch (RemoteException e) { 24394be6100218126ce6a08bf1f56209578500b361fRoboErik Log.e(TAG, "Error creating media controller in setMediaSession.", e); 24494be6100218126ce6a08bf1f56209578500b361fRoboErik } 24594be6100218126ce6a08bf1f56209578500b361fRoboErik if (mMediaController != null) { 24694be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.registerCallback(mControllerCallback); 247eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 24894be6100218126ce6a08bf1f56209578500b361fRoboErik MediaMetadataCompat metadata = mMediaController == null ? null 24994be6100218126ce6a08bf1f56209578500b361fRoboErik : mMediaController.getMetadata(); 25094be6100218126ce6a08bf1f56209578500b361fRoboErik mDescription = metadata == null ? null : metadata.getDescription(); 25194be6100218126ce6a08bf1f56209578500b361fRoboErik mState = mMediaController == null ? null : mMediaController.getPlaybackState(); 25294be6100218126ce6a08bf1f56209578500b361fRoboErik update(); 253eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 254eff7719415542ba819054863b0995f07742a7a8aJeff Brown 255eff7719415542ba819054863b0995f07742a7a8aJeff Brown /** 25694be6100218126ce6a08bf1f56209578500b361fRoboErik * Gets the description being used by the default UI. 25794be6100218126ce6a08bf1f56209578500b361fRoboErik * 25894be6100218126ce6a08bf1f56209578500b361fRoboErik * @return The current description. 259eff7719415542ba819054863b0995f07742a7a8aJeff Brown */ 26094be6100218126ce6a08bf1f56209578500b361fRoboErik public MediaSessionCompat.Token getMediaSession() { 26194be6100218126ce6a08bf1f56209578500b361fRoboErik return mMediaController == null ? null : mMediaController.getSessionToken(); 262eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 263eff7719415542ba819054863b0995f07742a7a8aJeff Brown 26411417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 26511417b1cfde8f1749905f2d735623af9214148afJeff Brown protected void onCreate(Bundle savedInstanceState) { 26611417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onCreate(savedInstanceState); 26711417b1cfde8f1749905f2d735623af9214148afJeff Brown 268a09c7b30d3a5c53281db955eabce171e1aec6feaSungsoo Lim setContentView(R.layout.mr_controller_material_dialog_b); 269f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo 27006991009e52024cbb3dde550988e06149e77a269Jae Seo // Remove the neutral button. 27106991009e52024cbb3dde550988e06149e77a269Jae Seo findViewById(BUTTON_NEUTRAL_RES_ID).setVisibility(View.GONE); 27206991009e52024cbb3dde550988e06149e77a269Jae Seo 27394be6100218126ce6a08bf1f56209578500b361fRoboErik ClickListener listener = new ClickListener(); 274d6748a7926ebb2450337f9f0ff4d445c980344e5Jeff Brown 27506991009e52024cbb3dde550988e06149e77a269Jae Seo mDisconnectButton = (Button) findViewById(BUTTON_DISCONNECT_RES_ID); 27606991009e52024cbb3dde550988e06149e77a269Jae Seo mDisconnectButton.setText(R.string.mr_controller_disconnect); 27794be6100218126ce6a08bf1f56209578500b361fRoboErik mDisconnectButton.setOnClickListener(listener); 27811417b1cfde8f1749905f2d735623af9214148afJeff Brown 27906991009e52024cbb3dde550988e06149e77a269Jae Seo mStopCastingButton = (Button) findViewById(BUTTON_STOP_RES_ID); 28006991009e52024cbb3dde550988e06149e77a269Jae Seo mStopCastingButton.setText(R.string.mr_controller_stop); 28194be6100218126ce6a08bf1f56209578500b361fRoboErik mStopCastingButton.setOnClickListener(listener); 28211417b1cfde8f1749905f2d735623af9214148afJeff Brown 28306991009e52024cbb3dde550988e06149e77a269Jae Seo TypedValue value = new TypedValue(); 28406991009e52024cbb3dde550988e06149e77a269Jae Seo if (getContext().getTheme().resolveAttribute(R.attr.colorPrimary, value, true)) { 28506991009e52024cbb3dde550988e06149e77a269Jae Seo mDisconnectButton.setTextColor(value.data); 28606991009e52024cbb3dde550988e06149e77a269Jae Seo mStopCastingButton.setTextColor(value.data); 28706991009e52024cbb3dde550988e06149e77a269Jae Seo } 28806991009e52024cbb3dde550988e06149e77a269Jae Seo 2891ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mRouteNameTextView = (TextView) findViewById(R.id.mr_name); 2901ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mCloseButton = (ImageButton) findViewById(R.id.mr_close); 291b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim mCloseButton.setOnClickListener(listener); 2921ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mCustomControlLayout = (FrameLayout) findViewById(R.id.mr_custom_control); 2932b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang mDefaultControlLayout = (FrameLayout) findViewById(R.id.mr_default_control); 2947ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim mArtView = (ImageView) findViewById(R.id.mr_art); 2956051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 2968e1281a26eaabd6422fd84c11010134a0a9c3338Jaewan Kim mMediaControlLayout = (LinearLayout) findViewById(R.id.mr_media_control); 2972c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mMediaMainControlLayout = (LinearLayout) findViewById(R.id.mr_media_main_control); 2981ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mDividerView = findViewById(R.id.mr_control_divider); 2991ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 3001ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlaybackControl = (RelativeLayout) findViewById(R.id.mr_playback_control); 3011ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mTitleView = (TextView) findViewById(R.id.mr_control_title); 3021ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mSubtitleView = (TextView) findViewById(R.id.mr_control_subtitle); 3031ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton = (ImageButton) findViewById(R.id.mr_control_play_pause); 3041ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setOnClickListener(listener); 3051ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 3061ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeControl = (LinearLayout) findViewById(R.id.mr_volume_control); 3071ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeSlider = (SeekBar) findViewById(R.id.mr_volume_slider); 308435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeSlider.setTag(VOLUME_SLIDER_TAG_MASTER); 309435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeChangeListener = new VolumeChangeListener(); 310435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeSlider.setOnSeekBarChangeListener(mVolumeChangeListener); 3111ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 3121ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim TypedArray styledAttributes = getContext().obtainStyledAttributes(new int[] { 3131ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim R.attr.mediaRouteExpandGroupDrawable, 3141ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim R.attr.mediaRouteCollapseGroupDrawable 3151ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim }); 3161ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim final Drawable expandGroupDrawable = styledAttributes.getDrawable(0); 3171ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim final Drawable collapseGroupDrawable = styledAttributes.getDrawable(1); 3181ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim styledAttributes.recycle(); 3191ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 320c2b193ac8bed52e8059178a80cb972e8229e528cJae Seo final String expandGroupDescription = getContext().getString( 321c2b193ac8bed52e8059178a80cb972e8229e528cJae Seo R.string.mr_controller_expand_group); 322c2b193ac8bed52e8059178a80cb972e8229e528cJae Seo final String collapseGroupDescription = getContext().getString( 323c2b193ac8bed52e8059178a80cb972e8229e528cJae Seo R.string.mr_controller_collapse_group); 324c2b193ac8bed52e8059178a80cb972e8229e528cJae Seo 3257ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim mVolumeGroupList = (ListView)findViewById(R.id.mr_volume_group_list); 3261ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mGroupExpandCollapseButton = (ImageButton) findViewById(R.id.mr_group_expand_collapse); 3271ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mGroupExpandCollapseButton.setOnClickListener(new View.OnClickListener() { 3281ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim @Override 3291ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim public void onClick(View v) { 3302b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang mIsGroupExpanded = !mIsGroupExpanded; 3312b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang if (mIsGroupExpanded) { 3321ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mGroupExpandCollapseButton.setImageDrawable(collapseGroupDrawable); 333c2b193ac8bed52e8059178a80cb972e8229e528cJae Seo mGroupExpandCollapseButton.setContentDescription(collapseGroupDescription); 3341ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeGroupList.setVisibility(View.VISIBLE); 3351ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeGroupList.setAdapter( 3361ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim new VolumeGroupAdapter(getContext(), getGroup().getRoutes())); 3371ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 3381ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mGroupExpandCollapseButton.setImageDrawable(expandGroupDrawable); 339c2b193ac8bed52e8059178a80cb972e8229e528cJae Seo mGroupExpandCollapseButton.setContentDescription(expandGroupDescription); 3401ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeGroupList.setVisibility(View.GONE); 3411ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 3422c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim updateLayoutHeight(); 3431ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 3441ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim }); 34511417b1cfde8f1749905f2d735623af9214148afJeff Brown 3467ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim mCustomControlView = onCreateMediaControlView(savedInstanceState); 3477ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim if (mCustomControlView != null) { 3481ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mCustomControlLayout.addView(mCustomControlView); 3491ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mCustomControlLayout.setVisibility(View.VISIBLE); 3507ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim mArtView.setVisibility(View.GONE); 35111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 35286a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo mCreated = true; 353d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo updateLayout(); 354d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo } 355d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo 356d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo /** 357d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo * Sets the width of the dialog. Also called when configuration changes. 358d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo */ 359d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo void updateLayout() { 360d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo int width = MediaRouteDialogHelper.getDialogWidth(getContext()); 361d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo getWindow().setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT); 362d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo 363d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo View decorView = getWindow().getDecorView(); 364d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo mDialogContentWidth = width - decorView.getPaddingLeft() - decorView.getPaddingRight(); 365d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo 366c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim Resources res = getContext().getResources(); 367c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim mVolumeGroupListItemIconSize = res.getDimensionPixelSize( 368c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim R.dimen.mr_controller_volume_group_list_item_icon_size); 369c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim mVolumeGroupListItemHeight = res.getDimensionPixelSize( 370c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim R.dimen.mr_controller_volume_group_list_item_height); 371c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim mVolumeGroupListMaxHeight = res.getDimensionPixelSize( 372c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim R.dimen.mr_controller_volume_group_list_max_height); 373c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim 374c74ed2dfd8328da1f1786f1e4fb07f0e8eebd35bJae Seo // Ensure the mArtView is updated. 375c74ed2dfd8328da1f1786f1e4fb07f0e8eebd35bJae Seo mArtIconBitmap = null; 376c74ed2dfd8328da1f1786f1e4fb07f0e8eebd35bJae Seo mArtIconUri = null; 3777ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim update(); 37811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 37911417b1cfde8f1749905f2d735623af9214148afJeff Brown 38011417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 38111417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onAttachedToWindow() { 38211417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onAttachedToWindow(); 383e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mAttachedToWindow = true; 38411417b1cfde8f1749905f2d735623af9214148afJeff Brown 38511417b1cfde8f1749905f2d735623af9214148afJeff Brown mRouter.addCallback(MediaRouteSelector.EMPTY, mCallback, 38611417b1cfde8f1749905f2d735623af9214148afJeff Brown MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS); 387e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik setMediaSession(mRouter.getMediaSessionToken()); 38811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 38911417b1cfde8f1749905f2d735623af9214148afJeff Brown 39011417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 39111417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onDetachedFromWindow() { 39211417b1cfde8f1749905f2d735623af9214148afJeff Brown mRouter.removeCallback(mCallback); 393e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik setMediaSession(null); 394e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mAttachedToWindow = false; 39511417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onDetachedFromWindow(); 39611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 39711417b1cfde8f1749905f2d735623af9214148afJeff Brown 39811417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 39911417b1cfde8f1749905f2d735623af9214148afJeff Brown public boolean onKeyDown(int keyCode, KeyEvent event) { 400ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 401ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 402ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown mRoute.requestUpdateVolume(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ? -1 : 1); 403ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown return true; 40411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 40511417b1cfde8f1749905f2d735623af9214148afJeff Brown return super.onKeyDown(keyCode, event); 40611417b1cfde8f1749905f2d735623af9214148afJeff Brown } 40711417b1cfde8f1749905f2d735623af9214148afJeff Brown 40811417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 40911417b1cfde8f1749905f2d735623af9214148afJeff Brown public boolean onKeyUp(int keyCode, KeyEvent event) { 410ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 411ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 412ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown return true; 41311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 41411417b1cfde8f1749905f2d735623af9214148afJeff Brown return super.onKeyUp(keyCode, event); 41511417b1cfde8f1749905f2d735623af9214148afJeff Brown } 41611417b1cfde8f1749905f2d735623af9214148afJeff Brown 4177ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim private void update() { 41811417b1cfde8f1749905f2d735623af9214148afJeff Brown if (!mRoute.isSelected() || mRoute.isDefault()) { 41911417b1cfde8f1749905f2d735623af9214148afJeff Brown dismiss(); 4207ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim return; 42111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 42294be6100218126ce6a08bf1f56209578500b361fRoboErik if (!mCreated) { 4237ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim return; 42494be6100218126ce6a08bf1f56209578500b361fRoboErik } 4252ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown 4267ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim mRouteNameTextView.setText(mRoute.getName()); 42706991009e52024cbb3dde550988e06149e77a269Jae Seo mDisconnectButton.setVisibility(mRoute.canDisconnect() ? View.VISIBLE : View.GONE); 42894be6100218126ce6a08bf1f56209578500b361fRoboErik 4297ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim if (mCustomControlView == null) { 430005482649154d0970693b3967241eb4d2cb22003Jaewan Kim if (mFetchArtTask != null) { 431005482649154d0970693b3967241eb4d2cb22003Jaewan Kim mFetchArtTask.cancel(true); 43266937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang } 433005482649154d0970693b3967241eb4d2cb22003Jaewan Kim mFetchArtTask = new FetchArtTask(); 434005482649154d0970693b3967241eb4d2cb22003Jaewan Kim mFetchArtTask.execute(); 435f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 4361ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim updateVolumeControl(); 4371ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim updatePlaybackControl(); 4381ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 4391ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 4402c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim private boolean isPlaybackControlAvailable() { 4412c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim return mCustomControlView == null && (mDescription != null || mState != null); 4422c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4432c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 4443fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim /** 4453fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim * Returns the height of main media controller which includes playback control and master 4463fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim * volume control. 4473fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim */ 4482c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim private int getMainControllerHeight(boolean showPlaybackControl) { 4492c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int height = 0; 4502c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (showPlaybackControl || mVolumeControl.getVisibility() == View.VISIBLE) { 4512c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim height += mMediaMainControlLayout.getPaddingTop() 4522c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim + mMediaMainControlLayout.getPaddingBottom(); 4532c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (showPlaybackControl) { 4542c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim height += mPlaybackControl.getMeasuredHeight(); 4552c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4562c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (mVolumeControl.getVisibility() == View.VISIBLE) { 4572c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim height += mVolumeControl.getMeasuredHeight(); 4582c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4592c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (showPlaybackControl && mVolumeControl.getVisibility() == View.VISIBLE) { 4602c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim height += mDividerView.getMeasuredHeight(); 4612c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4622c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4632c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim return height; 4642c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4652c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 466aaa885dc21bf5f526e1d3897e26ade96e1fae9ccJaewan Kim private void updateMediaControlVisibility(boolean showPlaybackControl) { 46792fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang // TODO: Update the top and bottom padding of the control layout according to the display 46892fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang // height. 46992fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang mDividerView.setVisibility((mVolumeControl.getVisibility() == View.VISIBLE 470aaa885dc21bf5f526e1d3897e26ade96e1fae9ccJaewan Kim && showPlaybackControl) ? View.VISIBLE : View.GONE); 47192fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang mMediaControlLayout.setVisibility((mVolumeControl.getVisibility() == View.GONE 472f8e1601db320e5bde6cb5ddcd4ecea187e3d4362Sungsoo Lim && !showPlaybackControl) ? View.GONE : View.VISIBLE); 47386dcb627078ea297c4337ed634fc3fe874e23897Jae Seo } 47486dcb627078ea297c4337ed634fc3fe874e23897Jae Seo 47586dcb627078ea297c4337ed634fc3fe874e23897Jae Seo private void updateLayoutHeight() { 47686dcb627078ea297c4337ed634fc3fe874e23897Jae Seo // We need to defer the update until the first layout has occurred, as we don't yet know the 47786dcb627078ea297c4337ed634fc3fe874e23897Jae Seo // overall visible display size in which the window this view is attached to has been 47886dcb627078ea297c4337ed634fc3fe874e23897Jae Seo // positioned in. 47986dcb627078ea297c4337ed634fc3fe874e23897Jae Seo ViewTreeObserver observer = mDefaultControlLayout.getViewTreeObserver(); 48086dcb627078ea297c4337ed634fc3fe874e23897Jae Seo observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 48186dcb627078ea297c4337ed634fc3fe874e23897Jae Seo @Override 48286dcb627078ea297c4337ed634fc3fe874e23897Jae Seo public void onGlobalLayout() { 48386dcb627078ea297c4337ed634fc3fe874e23897Jae Seo mDefaultControlLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this); 48486dcb627078ea297c4337ed634fc3fe874e23897Jae Seo updateLayoutHeightInternal(); 48586dcb627078ea297c4337ed634fc3fe874e23897Jae Seo } 48686dcb627078ea297c4337ed634fc3fe874e23897Jae Seo }); 48792fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang } 48892fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang 4893fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim /** 4903fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim * Updates the height of views and hide artwork or metadata if space is limited. 4913fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim */ 49286dcb627078ea297c4337ed634fc3fe874e23897Jae Seo private void updateLayoutHeightInternal() { 4932c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (mCustomControlView != null) { 4942c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim return; 4952c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 496aaa885dc21bf5f526e1d3897e26ade96e1fae9ccJaewan Kim updateMediaControlVisibility(isPlaybackControlAvailable()); 4972c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim View decorView = getWindow().getDecorView(); 4982c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim decorView.measure( 4992c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim MeasureSpec.makeMeasureSpec(getWindow().getAttributes().width, MeasureSpec.EXACTLY), 5002c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim MeasureSpec.UNSPECIFIED); 5012c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int artViewHeight = 0; 5022c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (mArtView.getDrawable() instanceof BitmapDrawable) { 5032c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim Bitmap art = ((BitmapDrawable) mArtView.getDrawable()).getBitmap(); 5042c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (art != null) { 5052c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim artViewHeight = getDesiredArtHeight(art.getWidth(), art.getHeight()); 5062c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mArtView.setScaleType(art.getWidth() >= art.getHeight() 5072c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim ? ImageView.ScaleType.FIT_XY : ImageView.ScaleType.FIT_CENTER); 5082c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5092c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5102c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int mainControllerHeight = getMainControllerHeight(isPlaybackControlAvailable()); 5112c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int volumeGroupListCount = mVolumeGroupList.getVisibility() == View.VISIBLE 5122c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim ? mVolumeGroupList.getAdapter().getCount() : 0; 513c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim // Scale down volume group list items in landscape mode. 514c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim for (int i = 0; i < volumeGroupListCount; i++) { 515c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim View item = mVolumeGroupList.getChildAt(i); 516c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim if (item != null) { 517c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim setLayoutHeight(item, mVolumeGroupListItemHeight); 518c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim setLayoutHeight(item.findViewById(R.id.mr_volume_item_icon), 519c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim mVolumeGroupListItemIconSize); 520c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim } 521c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim } 52240181af8431b704013f596a5ac298a06174d4d82Jaewan Kim int volumeGroupHeight = (volumeGroupListCount == 0) ? 0 523c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim : mVolumeGroupListItemHeight * volumeGroupListCount + mVolumeGroupListPaddingTop; 52419d268075834665bf62567b224dcd3549c92d3c3Jae Seo volumeGroupHeight = Math.min(volumeGroupHeight, mVolumeGroupListMaxHeight); 52519d268075834665bf62567b224dcd3549c92d3c3Jae Seo 5268367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim int desiredControlLayoutHeight = 5272c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim Math.max(artViewHeight, volumeGroupHeight) + mainControllerHeight; 5282c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim Rect visibleRect = new Rect(); 5292c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim decorView.getWindowVisibleDisplayFrame(visibleRect); 5302c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Height of non-control views in decor view. 5312c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // This includes title bar, button bar, and dialog's vertical padding which should be 5322c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // always shown. 5332c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int nonControlViewHeight = decorView.getMeasuredHeight() 5342c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim - mDefaultControlLayout.getMeasuredHeight(); 5352c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Maximum allowed height for controls to fit screen. 5362c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int maximumControlViewHeight = visibleRect.height() - nonControlViewHeight; 5372c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 5383fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim // Show artwork if it fits the screen and expanded volume group list has fewer than 3 items. 5393fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim if (artViewHeight > 0 && volumeGroupListCount < 3 5408367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim && desiredControlLayoutHeight <= maximumControlViewHeight) { 5412c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mArtView.setVisibility(View.VISIBLE); 5422c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim setLayoutHeight(mArtView, artViewHeight); 5432c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } else { 5442c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mArtView.setVisibility(View.GONE); 5452c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim artViewHeight = 0; 5468367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim desiredControlLayoutHeight = volumeGroupHeight + mainControllerHeight; 5472c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5482c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Show control if it fits the screen 5492c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (isPlaybackControlAvailable() 5508367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim && desiredControlLayoutHeight <= maximumControlViewHeight) { 5512c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mPlaybackControl.setVisibility(View.VISIBLE); 5522c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } else { 5532c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mPlaybackControl.setVisibility(View.GONE); 5542c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 555aaa885dc21bf5f526e1d3897e26ade96e1fae9ccJaewan Kim updateMediaControlVisibility(mPlaybackControl.getVisibility() == View.VISIBLE); 5562c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mainControllerHeight = getMainControllerHeight( 5572c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mPlaybackControl.getVisibility() == View.VISIBLE); 5588367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim desiredControlLayoutHeight = 5592c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim Math.max(artViewHeight, volumeGroupHeight) + mainControllerHeight; 5602c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 5612c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Limit the volume group list height to fit the screen. 5628367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim if (desiredControlLayoutHeight > maximumControlViewHeight) { 5638367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim volumeGroupHeight -= (desiredControlLayoutHeight - maximumControlViewHeight); 5648367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim desiredControlLayoutHeight = maximumControlViewHeight; 5652c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5662c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim setLayoutHeight(mVolumeGroupList, volumeGroupHeight); 5678367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim setLayoutHeight(mDefaultControlLayout, desiredControlLayoutHeight); 5682c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5692c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 5701ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private void updateVolumeControl() { 5711ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (!mVolumeSliderTouched) { 5727447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim if (isVolumeControlAvailable(mRoute)) { 5731ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeControl.setVisibility(View.VISIBLE); 5741ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeSlider.setMax(mRoute.getVolumeMax()); 5751ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeSlider.setProgress(mRoute.getVolume()); 5761ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (USE_GROUP) { 5771ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (getGroup() == null) { 5781ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mGroupExpandCollapseButton.setVisibility(View.GONE); 5791ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 5801ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mGroupExpandCollapseButton.setVisibility(View.VISIBLE); 5811ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim VolumeGroupAdapter adapter = 5821ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim (VolumeGroupAdapter) mVolumeGroupList.getAdapter(); 5831ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (adapter != null) { 5841ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim adapter.notifyDataSetChanged(); 5851ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 5861ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 5871ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 5881ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 5891ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeControl.setVisibility(View.GONE); 5901ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 5912c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim updateLayoutHeight(); 5927447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim } else if (mVolumeControl.getVisibility() == View.VISIBLE) { 5937447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim mVolumeSlider.setProgress(mRoute.getVolume()); 5947447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim if (mIsGroupExpanded) { 5957447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim for (int i = 0; i < mVolumeGroupList.getChildCount(); ++i) { 5967447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim MediaRouter.RouteInfo route = getGroup().getRouteAt(i); 5977447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim if (isVolumeControlAvailable(route)) { 5987447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim SeekBar volumeSlider = (SeekBar) mVolumeGroupList.getChildAt(i) 5997447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim .findViewById(R.id.mr_volume_slider); 6007447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim volumeSlider.setProgress(route.getVolume()); 6017447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim } 6027447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim } 6037447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim } 6041ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 6051ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 6061ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 6071ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private void updatePlaybackControl() { 6082c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (isPlaybackControlAvailable()) { 6091ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim CharSequence title = mDescription == null ? null : mDescription.getTitle(); 6101ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean hasTitle = !TextUtils.isEmpty(title); 6111ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 6121ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim CharSequence subtitle = mDescription == null ? null : mDescription.getSubtitle(); 6131ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean hasSubtitle = !TextUtils.isEmpty(subtitle); 6141ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 6158fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang boolean showTitle = false; 6168fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang boolean showSubtitle = false; 6178fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang if (mRoute.getPresentationDisplayId() 6188fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang != MediaRouter.RouteInfo.PRESENTATION_DISPLAY_ID_NONE) { 6198fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang // The user is currently casting screen. 6208fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mTitleView.setText(R.string.mr_controller_casting_screen); 6218fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang showTitle = true; 6228fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang } else if (mState == null || mState.getState() == PlaybackStateCompat.STATE_NONE) { 6238fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mTitleView.setText(R.string.mr_controller_no_media_selected); 6248fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang showTitle = true; 6258fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang } else if (!hasTitle && !hasSubtitle) { 6268fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mTitleView.setText(R.string.mr_controller_no_info_available); 6278fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang showTitle = true; 6281ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 6298fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang if (hasTitle) { 6308fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mTitleView.setText(title); 6318fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang showTitle = true; 6328fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang } 6338fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang if (hasSubtitle) { 6348fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mSubtitleView.setText(subtitle); 6358fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang showSubtitle = true; 6368fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang } 6371ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 6388fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mTitleView.setVisibility(showTitle ? View.VISIBLE : View.GONE); 6398fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mSubtitleView.setVisibility(showSubtitle ? View.VISIBLE : View.GONE); 6408fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang 6411ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (mState != null) { 6421ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean isPlaying = mState.getState() == PlaybackStateCompat.STATE_BUFFERING 6431ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim || mState.getState() == PlaybackStateCompat.STATE_PLAYING; 6441ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean supportsPlay = (mState.getActions() & (PlaybackStateCompat.ACTION_PLAY 6451ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0; 6461ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean supportsPause = (mState.getActions() & (PlaybackStateCompat.ACTION_PAUSE 6471ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0; 6481ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (isPlaying && supportsPause) { 6491ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setVisibility(View.VISIBLE); 6501ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setImageResource(MediaRouterThemeHelper.getThemeResource( 6511ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim getContext(), R.attr.mediaRoutePauseDrawable)); 6521ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setContentDescription(getContext().getResources() 6531ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim .getText(R.string.mr_controller_pause)); 6541ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else if (!isPlaying && supportsPlay) { 6551ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setVisibility(View.VISIBLE); 6561ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setImageResource(MediaRouterThemeHelper.getThemeResource( 6571ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim getContext(), R.attr.mediaRoutePlayDrawable)); 6581ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setContentDescription(getContext().getResources() 6591ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim .getText(R.string.mr_controller_play)); 6601ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 6611ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setVisibility(View.GONE); 6621ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 6631ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 6641ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 6652c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim updateLayoutHeight(); 6662b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang } 6672b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang 6687447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim private boolean isVolumeControlAvailable(MediaRouter.RouteInfo route) { 6697447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim return mVolumeControlEnabled && route.getVolumeHandling() 6707447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim == MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE; 671f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 672f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 673be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang private static void setLayoutHeight(View view, int height) { 674be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang ViewGroup.LayoutParams lp = view.getLayoutParams(); 675be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang lp.height = height; 676be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang view.setLayoutParams(lp); 677be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang } 678be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang 67913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim /** 68013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim * Returns desired art height to fit into controller dialog. 68113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim */ 68213d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim private int getDesiredArtHeight(int originalWidth, int originalHeight) { 68313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim if (originalWidth >= originalHeight) { 68413d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // For landscape art, fit width to dialog width. 685f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo return (int) ((float) mDialogContentWidth * originalHeight / originalWidth + 0.5f); 68613d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim } 68713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // For portrait art, fit height to 16:9 ratio case's height. 688f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo return (int) ((float) mDialogContentWidth * 9 / 16 + 0.5f); 68913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim } 69013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim 69111417b1cfde8f1749905f2d735623af9214148afJeff Brown private final class MediaRouterCallback extends MediaRouter.Callback { 69211417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 69311417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route) { 69411417b1cfde8f1749905f2d735623af9214148afJeff Brown update(); 69511417b1cfde8f1749905f2d735623af9214148afJeff Brown } 69611417b1cfde8f1749905f2d735623af9214148afJeff Brown 69711417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 69811417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo route) { 69911417b1cfde8f1749905f2d735623af9214148afJeff Brown update(); 70011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 70111417b1cfde8f1749905f2d735623af9214148afJeff Brown 70211417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 70311417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteVolumeChanged(MediaRouter router, MediaRouter.RouteInfo route) { 70411417b1cfde8f1749905f2d735623af9214148afJeff Brown if (route == mRoute) { 7051ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim updateVolumeControl(); 70694be6100218126ce6a08bf1f56209578500b361fRoboErik } 70794be6100218126ce6a08bf1f56209578500b361fRoboErik } 70894be6100218126ce6a08bf1f56209578500b361fRoboErik } 70994be6100218126ce6a08bf1f56209578500b361fRoboErik 71094be6100218126ce6a08bf1f56209578500b361fRoboErik private final class MediaControllerCallback extends MediaControllerCompat.Callback { 71194be6100218126ce6a08bf1f56209578500b361fRoboErik @Override 71294be6100218126ce6a08bf1f56209578500b361fRoboErik public void onSessionDestroyed() { 71394be6100218126ce6a08bf1f56209578500b361fRoboErik if (mMediaController != null) { 71494be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.unregisterCallback(mControllerCallback); 71594be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController = null; 71694be6100218126ce6a08bf1f56209578500b361fRoboErik } 71794be6100218126ce6a08bf1f56209578500b361fRoboErik } 71894be6100218126ce6a08bf1f56209578500b361fRoboErik 71994be6100218126ce6a08bf1f56209578500b361fRoboErik @Override 72094be6100218126ce6a08bf1f56209578500b361fRoboErik public void onPlaybackStateChanged(PlaybackStateCompat state) { 72194be6100218126ce6a08bf1f56209578500b361fRoboErik mState = state; 72294be6100218126ce6a08bf1f56209578500b361fRoboErik update(); 72394be6100218126ce6a08bf1f56209578500b361fRoboErik } 72494be6100218126ce6a08bf1f56209578500b361fRoboErik 72594be6100218126ce6a08bf1f56209578500b361fRoboErik @Override 72694be6100218126ce6a08bf1f56209578500b361fRoboErik public void onMetadataChanged(MediaMetadataCompat metadata) { 72794be6100218126ce6a08bf1f56209578500b361fRoboErik mDescription = metadata == null ? null : metadata.getDescription(); 72894be6100218126ce6a08bf1f56209578500b361fRoboErik update(); 72994be6100218126ce6a08bf1f56209578500b361fRoboErik } 73094be6100218126ce6a08bf1f56209578500b361fRoboErik } 73194be6100218126ce6a08bf1f56209578500b361fRoboErik 73294be6100218126ce6a08bf1f56209578500b361fRoboErik private final class ClickListener implements View.OnClickListener { 73394be6100218126ce6a08bf1f56209578500b361fRoboErik @Override 73494be6100218126ce6a08bf1f56209578500b361fRoboErik public void onClick(View v) { 73594be6100218126ce6a08bf1f56209578500b361fRoboErik int id = v.getId(); 73606991009e52024cbb3dde550988e06149e77a269Jae Seo if (id == BUTTON_STOP_RES_ID || id == BUTTON_DISCONNECT_RES_ID) { 73794be6100218126ce6a08bf1f56209578500b361fRoboErik if (mRoute.isSelected()) { 73806991009e52024cbb3dde550988e06149e77a269Jae Seo mRouter.unselect(id == BUTTON_STOP_RES_ID ? 73994be6100218126ce6a08bf1f56209578500b361fRoboErik MediaRouter.UNSELECT_REASON_STOPPED : 74094be6100218126ce6a08bf1f56209578500b361fRoboErik MediaRouter.UNSELECT_REASON_DISCONNECTED); 74194be6100218126ce6a08bf1f56209578500b361fRoboErik } 74294be6100218126ce6a08bf1f56209578500b361fRoboErik dismiss(); 7437ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim } else if (id == R.id.mr_control_play_pause) { 74494be6100218126ce6a08bf1f56209578500b361fRoboErik if (mMediaController != null && mState != null) { 74594be6100218126ce6a08bf1f56209578500b361fRoboErik if (mState.getState() == PlaybackStateCompat.STATE_PLAYING) { 74694be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.getTransportControls().pause(); 74794be6100218126ce6a08bf1f56209578500b361fRoboErik } else { 74894be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.getTransportControls().play(); 74994be6100218126ce6a08bf1f56209578500b361fRoboErik } 75094be6100218126ce6a08bf1f56209578500b361fRoboErik } 7511ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else if (id == R.id.mr_close) { 752b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim dismiss(); 75311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 75411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 75511417b1cfde8f1749905f2d735623af9214148afJeff Brown } 756005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 757435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim private class VolumeChangeListener implements OnSeekBarChangeListener { 758435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim private final Runnable mStopTrackingTouch = new Runnable() { 7596051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo @Override 760435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim public void run() { 761435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim if (mVolumeSliderTouched) { 762435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeSliderTouched = false; 763435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim updateVolumeControl(); 7646051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 7656051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 766435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim }; 7676051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 768435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim @Override 769435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim public void onStartTrackingTouch(SeekBar seekBar) { 770435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim if (mVolumeSliderTouched) { 771435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeSlider.removeCallbacks(mStopTrackingTouch); 772435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } else { 773435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeSliderTouched = true; 7746051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 775435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } 7766051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 777435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim @Override 778435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim public void onStopTrackingTouch(SeekBar seekBar) { 779435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim // Defer resetting mVolumeSliderTouched to allow the media route provider 780435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim // a little time to settle into its new state and publish the final 781435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim // volume update. 782435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeSlider.postDelayed(mStopTrackingTouch, VOLUME_UPDATE_DELAY_MILLIS); 783435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } 784435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim 785435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim @Override 786435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 787435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim if (fromUser) { 788435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim int tag = (int) seekBar.getTag(); 789435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim if (tag == VOLUME_SLIDER_TAG_MASTER) { 790435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mRoute.requestSetVolume(progress); 791435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } else if (tag - VOLUME_SLIDER_TAG_BASE >= 0 792435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim && tag - VOLUME_SLIDER_TAG_BASE < getGroup().getRouteCount()) { 793435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim getGroup().getRouteAt(tag - VOLUME_SLIDER_TAG_BASE).requestSetVolume(progress); 794435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } 7956051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 796435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } 797435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } 798435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim 799435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim private class VolumeGroupAdapter extends ArrayAdapter<MediaRouter.RouteInfo> { 800435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim final static float DISABLED_ALPHA = .3f; 8016051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 8026051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo public VolumeGroupAdapter(Context context, List<MediaRouter.RouteInfo> objects) { 8036051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo super(context, 0, objects); 8046051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 8056051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 8066051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo @Override 8076051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo public View getView(final int position, View convertView, ViewGroup parent) { 8086051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo View v = convertView; 8096051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo if (v == null) { 8106051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo v = LayoutInflater.from(getContext()).inflate( 8112c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim R.layout.mr_controller_volume_item, parent, false); 8126051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 81319d268075834665bf62567b224dcd3549c92d3c3Jae Seo 8146051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo MediaRouter.RouteInfo route = getItem(position); 8156051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo if (route != null) { 8160e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo boolean isEnabled = route.isEnabled(); 8170e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo 8187ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim TextView routeName = (TextView) v.findViewById(R.id.mr_name); 8190e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo routeName.setEnabled(isEnabled); 8200e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo routeName.setText(route.getName()); 8216051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 822ea15dd5d0313d55452f552d8583eb230b2c9506fJaewan Kim MediaRouteVolumeSlider volumeSlider = 823ea15dd5d0313d55452f552d8583eb230b2c9506fJaewan Kim (MediaRouteVolumeSlider) v.findViewById(R.id.mr_volume_slider); 824435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim volumeSlider.setTag(VOLUME_SLIDER_TAG_BASE + position); 825ea15dd5d0313d55452f552d8583eb230b2c9506fJaewan Kim volumeSlider.setShowThumb(isEnabled); 8260e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo if (isEnabled) { 8277447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim if (isVolumeControlAvailable(route)) { 8280e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setMax(route.getVolumeMax()); 8290e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setProgress(route.getVolume()); 830435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim volumeSlider.setOnSeekBarChangeListener(mVolumeChangeListener); 831ea15dd5d0313d55452f552d8583eb230b2c9506fJaewan Kim volumeSlider.setEnabled(true); 8320e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo } else { 8330e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setMax(100); 8340e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setProgress(100); 8350e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setEnabled(false); 8360e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo } 8370e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo } 8380e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo 8390e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo ImageView volumeItemIcon = 8407ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim (ImageView) v.findViewById(R.id.mr_volume_item_icon); 84177367b4a1871417198d0399d9ad074314c758567Jae Seo volumeItemIcon.setAlpha(isEnabled ? 255 : (int) (255 * DISABLED_ALPHA)); 8426051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 8436051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo return v; 8446051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 8456051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 8466051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 847005482649154d0970693b3967241eb4d2cb22003Jaewan Kim private class FetchArtTask extends AsyncTask<Void, Void, Bitmap> { 8488bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo final Bitmap mIconBitmap; 8498bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo final Uri mIconUri; 8508bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo int mBackgroundColor; 8518bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo 8528bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo FetchArtTask() { 8538bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mIconBitmap = mDescription == null ? null : mDescription.getIconBitmap(); 8548bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mIconUri = mDescription == null ? null : mDescription.getIconUri(); 8558bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } 8568bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo 8578bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo @Override 8588bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo protected void onPreExecute() { 8598bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo if (mArtIconBitmap == mIconBitmap && mArtIconUri == mIconUri) { 8608bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo // Already handled the current art. 8618bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo cancel(true); 8628bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } 8638bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } 864005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 865005482649154d0970693b3967241eb4d2cb22003Jaewan Kim @Override 866005482649154d0970693b3967241eb4d2cb22003Jaewan Kim protected Bitmap doInBackground(Void... arg) { 86713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim Bitmap art = null; 8688bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo if (mIconBitmap != null) { 8698bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo art = mIconBitmap; 8708bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } else if (mIconUri != null) { 8718bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo String scheme = mIconUri.getScheme(); 872005482649154d0970693b3967241eb4d2cb22003Jaewan Kim if (!(ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme) 873005482649154d0970693b3967241eb4d2cb22003Jaewan Kim || ContentResolver.SCHEME_CONTENT.equals(scheme) 874005482649154d0970693b3967241eb4d2cb22003Jaewan Kim || ContentResolver.SCHEME_FILE.equals(scheme))) { 875005482649154d0970693b3967241eb4d2cb22003Jaewan Kim Log.w(TAG, "Icon Uri should point to local resources."); 876005482649154d0970693b3967241eb4d2cb22003Jaewan Kim return null; 877005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 878005482649154d0970693b3967241eb4d2cb22003Jaewan Kim BufferedInputStream stream = null; 879005482649154d0970693b3967241eb4d2cb22003Jaewan Kim try { 880005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream = new BufferedInputStream( 8818bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo getContext().getContentResolver().openInputStream(mIconUri)); 882005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 88313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // Query art size. 884005482649154d0970693b3967241eb4d2cb22003Jaewan Kim BitmapFactory.Options options = new BitmapFactory.Options(); 885005482649154d0970693b3967241eb4d2cb22003Jaewan Kim options.inJustDecodeBounds = true; 886005482649154d0970693b3967241eb4d2cb22003Jaewan Kim BitmapFactory.decodeStream(stream, null, options); 88713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim if (options.outWidth == 0 || options.outHeight == 0) { 88813d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim return null; 88913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim } 89013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // Rewind the stream in order to restart art decoding. 891005482649154d0970693b3967241eb4d2cb22003Jaewan Kim try { 892005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream.reset(); 893005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } catch (IOException e) { 894005482649154d0970693b3967241eb4d2cb22003Jaewan Kim // Failed to rewind the stream, try to reopen it. 895005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream.close(); 896005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream = new BufferedInputStream(getContext().getContentResolver() 8978bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo .openInputStream(mIconUri)); 898005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 89913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // Calculate required size to decode the art and possibly resize it. 900005482649154d0970693b3967241eb4d2cb22003Jaewan Kim options.inJustDecodeBounds = false; 90113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim int reqHeight = getDesiredArtHeight(options.outWidth, options.outHeight); 90213d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim int ratio = options.outHeight / reqHeight; 903005482649154d0970693b3967241eb4d2cb22003Jaewan Kim options.inSampleSize = Math.max(1, Integer.highestOneBit(ratio)); 904005482649154d0970693b3967241eb4d2cb22003Jaewan Kim if (isCancelled()) { 905005482649154d0970693b3967241eb4d2cb22003Jaewan Kim return null; 906005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 90713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim art = BitmapFactory.decodeStream(stream, null, options); 908005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } catch (IOException e){ 9098bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo Log.w(TAG, "Unable to open: " + mIconUri, e); 910005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } finally { 911005482649154d0970693b3967241eb4d2cb22003Jaewan Kim if (stream != null) { 912005482649154d0970693b3967241eb4d2cb22003Jaewan Kim try { 913005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream.close(); 914005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } catch (IOException e) { 915005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 916005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 917005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 918005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 919145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim if (art != null && art.getWidth() < art.getHeight()) { 920145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim // Portrait art requires background color. 921145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim Palette palette = new Palette.Builder(art).maximumColorCount(1).generate(); 922be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang mBackgroundColor = palette.getSwatches().isEmpty() 923145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim ? 0 : palette.getSwatches().get(0).getRgb(); 924005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 92513d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim return art; 926005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 927005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 928005482649154d0970693b3967241eb4d2cb22003Jaewan Kim @Override 929005482649154d0970693b3967241eb4d2cb22003Jaewan Kim protected void onCancelled() { 930005482649154d0970693b3967241eb4d2cb22003Jaewan Kim mFetchArtTask = null; 931005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 932005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 933005482649154d0970693b3967241eb4d2cb22003Jaewan Kim @Override 93413d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim protected void onPostExecute(Bitmap art) { 935005482649154d0970693b3967241eb4d2cb22003Jaewan Kim mFetchArtTask = null; 9368bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo if (mArtIconBitmap != mIconBitmap || mArtIconUri != mIconUri) { 9378bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mArtIconBitmap = mIconBitmap; 9388bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mArtIconUri = mIconUri; 9398bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo 9408bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mArtView.setImageBitmap(art); 9418bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mArtView.setBackgroundColor(mBackgroundColor); 9422c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim updateLayoutHeight(); 9438bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } 944005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 945005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 9466051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo} 947