MediaRouteControllerDialog.java revision 328f1006c17ddeb3eb563580bcd6638e1cfb4320
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; 24005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.graphics.Bitmap; 25005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.graphics.BitmapFactory; 262c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kimimport android.graphics.Rect; 2713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kimimport android.graphics.drawable.BitmapDrawable; 28005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.net.Uri; 29005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.os.AsyncTask; 3011417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.os.Bundle; 3194be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.os.RemoteException; 3294be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.MediaDescriptionCompat; 3394be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.MediaMetadataCompat; 3494be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.MediaControllerCompat; 3594be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.MediaSessionCompat; 3694be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.support.v4.media.session.PlaybackStateCompat; 37ee7ae661b02471fe598566b1e90adbacda240b0bJae Seoimport android.support.v4.view.accessibility.AccessibilityEventCompat; 38005482649154d0970693b3967241eb4d2cb22003Jaewan Kimimport android.support.v7.graphics.Palette; 3911417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouteSelector; 4011417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.media.MediaRouter; 4111417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.support.v7.mediarouter.R; 4294be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.text.TextUtils; 4394be6100218126ce6a08bf1f56209578500b361fRoboErikimport android.util.Log; 4406991009e52024cbb3dde550988e06149e77a269Jae Seoimport android.util.TypedValue; 4511417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.KeyEvent; 466051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.view.LayoutInflater; 4711417b1cfde8f1749905f2d735623af9214148afJeff Brownimport android.view.View; 4840dd800ece983a94ea6a26a27481da50f489e7c8Jaewan Kimimport android.view.View.MeasureSpec; 496051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seoimport android.view.ViewGroup; 5086dcb627078ea297c4337ed634fc3fe874e23897Jae Seoimport android.view.ViewTreeObserver; 51ee7ae661b02471fe598566b1e90adbacda240b0bJae Seoimport android.view.accessibility.AccessibilityEvent; 52ee7ae661b02471fe598566b1e90adbacda240b0bJae Seoimport android.view.accessibility.AccessibilityManager; 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 80f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah // Time to wait before updating the volume when the user lets go of the seek bar 81f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah // to allow the route provider time to propagate the change and publish a new 82f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah // route descriptor. 83f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah private static final int VOLUME_UPDATE_DELAY_MILLIS = 250; 84435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim private static final int VOLUME_SLIDER_TAG_MASTER = 0; 85435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim private static final int VOLUME_SLIDER_TAG_BASE = 100; 86f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 8706991009e52024cbb3dde550988e06149e77a269Jae Seo private static final int BUTTON_NEUTRAL_RES_ID = android.R.id.button3; 8806991009e52024cbb3dde550988e06149e77a269Jae Seo private static final int BUTTON_DISCONNECT_RES_ID = android.R.id.button2; 8906991009e52024cbb3dde550988e06149e77a269Jae Seo private static final int BUTTON_STOP_RES_ID = android.R.id.button1; 9006991009e52024cbb3dde550988e06149e77a269Jae Seo 9111417b1cfde8f1749905f2d735623af9214148afJeff Brown private final MediaRouter mRouter; 9211417b1cfde8f1749905f2d735623af9214148afJeff Brown private final MediaRouterCallback mCallback; 9311417b1cfde8f1749905f2d735623af9214148afJeff Brown private final MediaRouter.RouteInfo mRoute; 9411417b1cfde8f1749905f2d735623af9214148afJeff Brown 95eff7719415542ba819054863b0995f07742a7a8aJeff Brown private boolean mCreated; 96e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private boolean mAttachedToWindow; 97e2148398ae5d03c22789aebc3d6359b5ff86c077Jae Seo 98f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo private int mDialogContentWidth; 9911417b1cfde8f1749905f2d735623af9214148afJeff Brown 1007ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim private View mCustomControlView; 10111417b1cfde8f1749905f2d735623af9214148afJeff Brown 10211417b1cfde8f1749905f2d735623af9214148afJeff Brown private Button mDisconnectButton; 10394be6100218126ce6a08bf1f56209578500b361fRoboErik private Button mStopCastingButton; 1041ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private ImageButton mPlayPauseButton; 105b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim private ImageButton mCloseButton; 106328f1006c17ddeb3eb563580bcd6638e1cfb4320Jaewan Kim private MediaRouteExpandCollapseButton mGroupExpandCollapseButton; 10794be6100218126ce6a08bf1f56209578500b361fRoboErik 1081ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private FrameLayout mCustomControlLayout; 1092b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang private FrameLayout mDefaultControlLayout; 11094be6100218126ce6a08bf1f56209578500b361fRoboErik private ImageView mArtView; 1111ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private TextView mTitleView; 1121ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private TextView mSubtitleView; 1137ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim private TextView mRouteNameTextView; 11494be6100218126ce6a08bf1f56209578500b361fRoboErik 115f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah private boolean mVolumeControlEnabled = true; 1162c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Layout for media controllers including play/pause button, volume slider, 1172c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // and group volume sliders. 1188e1281a26eaabd6422fd84c11010134a0a9c3338Jaewan Kim private LinearLayout mMediaControlLayout; 1192c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Layout for media controllers including play/pause button and volume slider. 1202c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim private LinearLayout mMediaMainControlLayout; 1211ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private RelativeLayout mPlaybackControl; 1221ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private LinearLayout mVolumeControl; 1231ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private View mDividerView; 1241ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 1256051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo private ListView mVolumeGroupList; 1261ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private SeekBar mVolumeSlider; 127435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim private VolumeChangeListener mVolumeChangeListener; 1281ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private boolean mVolumeSliderTouched; 129c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim private int mVolumeGroupListItemIconSize; 130c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim private int mVolumeGroupListItemHeight; 131c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim private int mVolumeGroupListMaxHeight; 132c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim private final int mVolumeGroupListPaddingTop; 133f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 13494be6100218126ce6a08bf1f56209578500b361fRoboErik private MediaControllerCompat mMediaController; 13594be6100218126ce6a08bf1f56209578500b361fRoboErik private MediaControllerCallback mControllerCallback; 13694be6100218126ce6a08bf1f56209578500b361fRoboErik private PlaybackStateCompat mState; 13794be6100218126ce6a08bf1f56209578500b361fRoboErik private MediaDescriptionCompat mDescription; 13894be6100218126ce6a08bf1f56209578500b361fRoboErik 139005482649154d0970693b3967241eb4d2cb22003Jaewan Kim private FetchArtTask mFetchArtTask; 1408bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo private Bitmap mArtIconBitmap; 1418bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo private Uri mArtIconUri; 1422b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang private boolean mIsGroupExpanded; 14311417b1cfde8f1749905f2d735623af9214148afJeff Brown 144ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo private final AccessibilityManager mAccessibilityManager; 145ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo 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); 161ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo mAccessibilityManager = 162ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo (AccessibilityManager) context.getSystemService(Context.ACCESSIBILITY_SERVICE); 16311417b1cfde8f1749905f2d735623af9214148afJeff Brown } 16411417b1cfde8f1749905f2d735623af9214148afJeff Brown 16511417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 16611417b1cfde8f1749905f2d735623af9214148afJeff Brown * Gets the route that this dialog is controlling. 16711417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 16811417b1cfde8f1749905f2d735623af9214148afJeff Brown public MediaRouter.RouteInfo getRoute() { 16911417b1cfde8f1749905f2d735623af9214148afJeff Brown return mRoute; 17011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 17111417b1cfde8f1749905f2d735623af9214148afJeff Brown 1726051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo private MediaRouter.RouteGroup getGroup() { 1736051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo if (mRoute instanceof MediaRouter.RouteGroup) { 1746051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo return (MediaRouter.RouteGroup) mRoute; 1756051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 1766051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo return null; 1776051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 1786051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 17911417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 18011417b1cfde8f1749905f2d735623af9214148afJeff Brown * Provides the subclass an opportunity to create a view that will 18111417b1cfde8f1749905f2d735623af9214148afJeff Brown * be included within the body of the dialog to offer additional media controls 18211417b1cfde8f1749905f2d735623af9214148afJeff Brown * for the currently playing content. 18311417b1cfde8f1749905f2d735623af9214148afJeff Brown * 18411417b1cfde8f1749905f2d735623af9214148afJeff Brown * @param savedInstanceState The dialog's saved instance state. 18511417b1cfde8f1749905f2d735623af9214148afJeff Brown * @return The media control view, or null if none. 18611417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 18711417b1cfde8f1749905f2d735623af9214148afJeff Brown public View onCreateMediaControlView(Bundle savedInstanceState) { 18811417b1cfde8f1749905f2d735623af9214148afJeff Brown return null; 18911417b1cfde8f1749905f2d735623af9214148afJeff Brown } 19011417b1cfde8f1749905f2d735623af9214148afJeff Brown 19111417b1cfde8f1749905f2d735623af9214148afJeff Brown /** 19211417b1cfde8f1749905f2d735623af9214148afJeff Brown * Gets the media control view that was created by {@link #onCreateMediaControlView(Bundle)}. 19311417b1cfde8f1749905f2d735623af9214148afJeff Brown * 19411417b1cfde8f1749905f2d735623af9214148afJeff Brown * @return The media control view, or null if none. 19511417b1cfde8f1749905f2d735623af9214148afJeff Brown */ 19611417b1cfde8f1749905f2d735623af9214148afJeff Brown public View getMediaControlView() { 1977ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim return mCustomControlView; 19811417b1cfde8f1749905f2d735623af9214148afJeff Brown } 19911417b1cfde8f1749905f2d735623af9214148afJeff Brown 200eff7719415542ba819054863b0995f07742a7a8aJeff Brown /** 201f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * Sets whether to enable the volume slider and volume control using the volume keys 202f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * when the route supports it. 203f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * <p> 204f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * The default value is true. 205f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * </p> 206f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah */ 207f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah public void setVolumeControlEnabled(boolean enable) { 208f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah if (mVolumeControlEnabled != enable) { 209f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah mVolumeControlEnabled = enable; 210f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah if (mCreated) { 2111ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim updateVolumeControl(); 212f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 213f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 214f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 215f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 216f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah /** 217f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * Returns whether to enable the volume slider and volume control using the volume keys 218f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah * when the route supports it. 219f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah */ 220f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah public boolean isVolumeControlEnabled() { 221f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah return mVolumeControlEnabled; 222f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 223f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 224f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah /** 22594be6100218126ce6a08bf1f56209578500b361fRoboErik * Set the session to use for metadata and transport controls. The dialog 22694be6100218126ce6a08bf1f56209578500b361fRoboErik * will listen to changes on this session and update the UI automatically in 22794be6100218126ce6a08bf1f56209578500b361fRoboErik * response to changes. 22894be6100218126ce6a08bf1f56209578500b361fRoboErik * 22994be6100218126ce6a08bf1f56209578500b361fRoboErik * @param sessionToken The token for the session to use. 230eff7719415542ba819054863b0995f07742a7a8aJeff Brown */ 231e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik private void setMediaSession(MediaSessionCompat.Token sessionToken) { 23294be6100218126ce6a08bf1f56209578500b361fRoboErik if (mMediaController != null) { 23394be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.unregisterCallback(mControllerCallback); 23494be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController = null; 23594be6100218126ce6a08bf1f56209578500b361fRoboErik } 23694be6100218126ce6a08bf1f56209578500b361fRoboErik if (sessionToken == null) { 23794be6100218126ce6a08bf1f56209578500b361fRoboErik return; 23894be6100218126ce6a08bf1f56209578500b361fRoboErik } 239e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik if (!mAttachedToWindow) { 240e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik return; 241e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik } 24294be6100218126ce6a08bf1f56209578500b361fRoboErik try { 24394be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController = new MediaControllerCompat(getContext(), sessionToken); 24494be6100218126ce6a08bf1f56209578500b361fRoboErik } catch (RemoteException e) { 24594be6100218126ce6a08bf1f56209578500b361fRoboErik Log.e(TAG, "Error creating media controller in setMediaSession.", e); 24694be6100218126ce6a08bf1f56209578500b361fRoboErik } 24794be6100218126ce6a08bf1f56209578500b361fRoboErik if (mMediaController != null) { 24894be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.registerCallback(mControllerCallback); 249eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 25094be6100218126ce6a08bf1f56209578500b361fRoboErik MediaMetadataCompat metadata = mMediaController == null ? null 25194be6100218126ce6a08bf1f56209578500b361fRoboErik : mMediaController.getMetadata(); 25294be6100218126ce6a08bf1f56209578500b361fRoboErik mDescription = metadata == null ? null : metadata.getDescription(); 25394be6100218126ce6a08bf1f56209578500b361fRoboErik mState = mMediaController == null ? null : mMediaController.getPlaybackState(); 25494be6100218126ce6a08bf1f56209578500b361fRoboErik update(); 255eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 256eff7719415542ba819054863b0995f07742a7a8aJeff Brown 257eff7719415542ba819054863b0995f07742a7a8aJeff Brown /** 25875dbda46b4ca20861e9d382b1662b3c34d20da8aInsun Kang * Gets the session to use for metadata and transport controls. 25994be6100218126ce6a08bf1f56209578500b361fRoboErik * 26075dbda46b4ca20861e9d382b1662b3c34d20da8aInsun Kang * @return The token for the session to use or null if none. 261eff7719415542ba819054863b0995f07742a7a8aJeff Brown */ 26294be6100218126ce6a08bf1f56209578500b361fRoboErik public MediaSessionCompat.Token getMediaSession() { 26394be6100218126ce6a08bf1f56209578500b361fRoboErik return mMediaController == null ? null : mMediaController.getSessionToken(); 264eff7719415542ba819054863b0995f07742a7a8aJeff Brown } 265eff7719415542ba819054863b0995f07742a7a8aJeff Brown 26611417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 26711417b1cfde8f1749905f2d735623af9214148afJeff Brown protected void onCreate(Bundle savedInstanceState) { 26811417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onCreate(savedInstanceState); 26911417b1cfde8f1749905f2d735623af9214148afJeff Brown 270a09c7b30d3a5c53281db955eabce171e1aec6feaSungsoo Lim setContentView(R.layout.mr_controller_material_dialog_b); 271f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo 27206991009e52024cbb3dde550988e06149e77a269Jae Seo // Remove the neutral button. 27306991009e52024cbb3dde550988e06149e77a269Jae Seo findViewById(BUTTON_NEUTRAL_RES_ID).setVisibility(View.GONE); 27406991009e52024cbb3dde550988e06149e77a269Jae Seo 27594be6100218126ce6a08bf1f56209578500b361fRoboErik ClickListener listener = new ClickListener(); 276d6748a7926ebb2450337f9f0ff4d445c980344e5Jeff Brown 27706991009e52024cbb3dde550988e06149e77a269Jae Seo mDisconnectButton = (Button) findViewById(BUTTON_DISCONNECT_RES_ID); 27806991009e52024cbb3dde550988e06149e77a269Jae Seo mDisconnectButton.setText(R.string.mr_controller_disconnect); 27994be6100218126ce6a08bf1f56209578500b361fRoboErik mDisconnectButton.setOnClickListener(listener); 28011417b1cfde8f1749905f2d735623af9214148afJeff Brown 28106991009e52024cbb3dde550988e06149e77a269Jae Seo mStopCastingButton = (Button) findViewById(BUTTON_STOP_RES_ID); 28206991009e52024cbb3dde550988e06149e77a269Jae Seo mStopCastingButton.setText(R.string.mr_controller_stop); 28394be6100218126ce6a08bf1f56209578500b361fRoboErik mStopCastingButton.setOnClickListener(listener); 28411417b1cfde8f1749905f2d735623af9214148afJeff Brown 28506991009e52024cbb3dde550988e06149e77a269Jae Seo TypedValue value = new TypedValue(); 28606991009e52024cbb3dde550988e06149e77a269Jae Seo if (getContext().getTheme().resolveAttribute(R.attr.colorPrimary, value, true)) { 28706991009e52024cbb3dde550988e06149e77a269Jae Seo mDisconnectButton.setTextColor(value.data); 28806991009e52024cbb3dde550988e06149e77a269Jae Seo mStopCastingButton.setTextColor(value.data); 28906991009e52024cbb3dde550988e06149e77a269Jae Seo } 29006991009e52024cbb3dde550988e06149e77a269Jae Seo 2911ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mRouteNameTextView = (TextView) findViewById(R.id.mr_name); 2921ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mCloseButton = (ImageButton) findViewById(R.id.mr_close); 293b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim mCloseButton.setOnClickListener(listener); 2941ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mCustomControlLayout = (FrameLayout) findViewById(R.id.mr_custom_control); 2952b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang mDefaultControlLayout = (FrameLayout) findViewById(R.id.mr_default_control); 2967ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim mArtView = (ImageView) findViewById(R.id.mr_art); 2976051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 2988e1281a26eaabd6422fd84c11010134a0a9c3338Jaewan Kim mMediaControlLayout = (LinearLayout) findViewById(R.id.mr_media_control); 2992c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mMediaMainControlLayout = (LinearLayout) findViewById(R.id.mr_media_main_control); 3001ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mDividerView = findViewById(R.id.mr_control_divider); 3011ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 3021ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlaybackControl = (RelativeLayout) findViewById(R.id.mr_playback_control); 3031ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mTitleView = (TextView) findViewById(R.id.mr_control_title); 3041ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mSubtitleView = (TextView) findViewById(R.id.mr_control_subtitle); 3051ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton = (ImageButton) findViewById(R.id.mr_control_play_pause); 3061ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setOnClickListener(listener); 3071ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 3081ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeControl = (LinearLayout) findViewById(R.id.mr_volume_control); 3091ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeSlider = (SeekBar) findViewById(R.id.mr_volume_slider); 310435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeSlider.setTag(VOLUME_SLIDER_TAG_MASTER); 311435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeChangeListener = new VolumeChangeListener(); 312435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeSlider.setOnSeekBarChangeListener(mVolumeChangeListener); 3131ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 314328f1006c17ddeb3eb563580bcd6638e1cfb4320Jaewan Kim mVolumeGroupList = (ListView) findViewById(R.id.mr_volume_group_list); 315328f1006c17ddeb3eb563580bcd6638e1cfb4320Jaewan Kim mGroupExpandCollapseButton = 316328f1006c17ddeb3eb563580bcd6638e1cfb4320Jaewan Kim (MediaRouteExpandCollapseButton) findViewById(R.id.mr_group_expand_collapse); 3171ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mGroupExpandCollapseButton.setOnClickListener(new View.OnClickListener() { 3181ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim @Override 3191ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim public void onClick(View v) { 3202b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang mIsGroupExpanded = !mIsGroupExpanded; 3212b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang if (mIsGroupExpanded) { 3221ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeGroupList.setVisibility(View.VISIBLE); 3231ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeGroupList.setAdapter( 3241ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim new VolumeGroupAdapter(getContext(), getGroup().getRoutes())); 3251ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 3261ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeGroupList.setVisibility(View.GONE); 3271ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 3282c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim updateLayoutHeight(); 3291ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 3301ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim }); 33111417b1cfde8f1749905f2d735623af9214148afJeff Brown 3327ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim mCustomControlView = onCreateMediaControlView(savedInstanceState); 3337ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim if (mCustomControlView != null) { 3341ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mCustomControlLayout.addView(mCustomControlView); 3351ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mCustomControlLayout.setVisibility(View.VISIBLE); 3367ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim mArtView.setVisibility(View.GONE); 33711417b1cfde8f1749905f2d735623af9214148afJeff Brown } 33886a802c8d09983d8725cccf59217e65d3e0c6373Jae Seo mCreated = true; 339d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo updateLayout(); 340d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo } 341d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo 342d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo /** 343d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo * Sets the width of the dialog. Also called when configuration changes. 344d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo */ 345d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo void updateLayout() { 346d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo int width = MediaRouteDialogHelper.getDialogWidth(getContext()); 347d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo getWindow().setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT); 348d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo 349d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo View decorView = getWindow().getDecorView(); 350d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo mDialogContentWidth = width - decorView.getPaddingLeft() - decorView.getPaddingRight(); 351d52e30f3736a821e45266c28c334756f5f7e55c3Jae Seo 352c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim Resources res = getContext().getResources(); 353c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim mVolumeGroupListItemIconSize = res.getDimensionPixelSize( 354c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim R.dimen.mr_controller_volume_group_list_item_icon_size); 355c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim mVolumeGroupListItemHeight = res.getDimensionPixelSize( 356c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim R.dimen.mr_controller_volume_group_list_item_height); 357c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim mVolumeGroupListMaxHeight = res.getDimensionPixelSize( 358c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim R.dimen.mr_controller_volume_group_list_max_height); 359c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim 360c74ed2dfd8328da1f1786f1e4fb07f0e8eebd35bJae Seo // Ensure the mArtView is updated. 361c74ed2dfd8328da1f1786f1e4fb07f0e8eebd35bJae Seo mArtIconBitmap = null; 362c74ed2dfd8328da1f1786f1e4fb07f0e8eebd35bJae Seo mArtIconUri = null; 3637ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim update(); 36411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 36511417b1cfde8f1749905f2d735623af9214148afJeff Brown 36611417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 36711417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onAttachedToWindow() { 36811417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onAttachedToWindow(); 369e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mAttachedToWindow = true; 37011417b1cfde8f1749905f2d735623af9214148afJeff Brown 37111417b1cfde8f1749905f2d735623af9214148afJeff Brown mRouter.addCallback(MediaRouteSelector.EMPTY, mCallback, 37211417b1cfde8f1749905f2d735623af9214148afJeff Brown MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS); 373e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik setMediaSession(mRouter.getMediaSessionToken()); 37411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 37511417b1cfde8f1749905f2d735623af9214148afJeff Brown 37611417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 37711417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onDetachedFromWindow() { 37811417b1cfde8f1749905f2d735623af9214148afJeff Brown mRouter.removeCallback(mCallback); 379e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik setMediaSession(null); 380e49860b0f76d8336c1d41831ed370b0ff94278efRoboErik mAttachedToWindow = false; 38111417b1cfde8f1749905f2d735623af9214148afJeff Brown super.onDetachedFromWindow(); 38211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 38311417b1cfde8f1749905f2d735623af9214148afJeff Brown 38411417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 38511417b1cfde8f1749905f2d735623af9214148afJeff Brown public boolean onKeyDown(int keyCode, KeyEvent event) { 386ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 387ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 388ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown mRoute.requestUpdateVolume(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ? -1 : 1); 389ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown return true; 39011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 39111417b1cfde8f1749905f2d735623af9214148afJeff Brown return super.onKeyDown(keyCode, event); 39211417b1cfde8f1749905f2d735623af9214148afJeff Brown } 39311417b1cfde8f1749905f2d735623af9214148afJeff Brown 39411417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 39511417b1cfde8f1749905f2d735623af9214148afJeff Brown public boolean onKeyUp(int keyCode, KeyEvent event) { 396ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 397ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 398ce8cbd614a64f94e54b936d66ecd14b6c1282ddfJeff Brown return true; 39911417b1cfde8f1749905f2d735623af9214148afJeff Brown } 40011417b1cfde8f1749905f2d735623af9214148afJeff Brown return super.onKeyUp(keyCode, event); 40111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 40211417b1cfde8f1749905f2d735623af9214148afJeff Brown 4037ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim private void update() { 40411417b1cfde8f1749905f2d735623af9214148afJeff Brown if (!mRoute.isSelected() || mRoute.isDefault()) { 40511417b1cfde8f1749905f2d735623af9214148afJeff Brown dismiss(); 4067ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim return; 40711417b1cfde8f1749905f2d735623af9214148afJeff Brown } 40894be6100218126ce6a08bf1f56209578500b361fRoboErik if (!mCreated) { 4097ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim return; 41094be6100218126ce6a08bf1f56209578500b361fRoboErik } 4112ef36d857302c5cd738c7c8bdec53d31feebebbaJeff Brown 4127ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim mRouteNameTextView.setText(mRoute.getName()); 41306991009e52024cbb3dde550988e06149e77a269Jae Seo mDisconnectButton.setVisibility(mRoute.canDisconnect() ? View.VISIBLE : View.GONE); 41494be6100218126ce6a08bf1f56209578500b361fRoboErik 4157ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim if (mCustomControlView == null) { 416005482649154d0970693b3967241eb4d2cb22003Jaewan Kim if (mFetchArtTask != null) { 417005482649154d0970693b3967241eb4d2cb22003Jaewan Kim mFetchArtTask.cancel(true); 41866937fc7dfe22c8c505bf735781d1f5b62f08e34Dongwon Kang } 419005482649154d0970693b3967241eb4d2cb22003Jaewan Kim mFetchArtTask = new FetchArtTask(); 420005482649154d0970693b3967241eb4d2cb22003Jaewan Kim mFetchArtTask.execute(); 421f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 4221ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim updateVolumeControl(); 4231ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim updatePlaybackControl(); 4241ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 4251ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 4262c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim private boolean isPlaybackControlAvailable() { 4272c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim return mCustomControlView == null && (mDescription != null || mState != null); 4282c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4292c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 4303fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim /** 4313fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim * Returns the height of main media controller which includes playback control and master 4323fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim * volume control. 4333fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim */ 4342c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim private int getMainControllerHeight(boolean showPlaybackControl) { 4352c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int height = 0; 4362c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (showPlaybackControl || mVolumeControl.getVisibility() == View.VISIBLE) { 4372c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim height += mMediaMainControlLayout.getPaddingTop() 4382c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim + mMediaMainControlLayout.getPaddingBottom(); 4392c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (showPlaybackControl) { 4402c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim height += mPlaybackControl.getMeasuredHeight(); 4412c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4422c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (mVolumeControl.getVisibility() == View.VISIBLE) { 4432c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim height += mVolumeControl.getMeasuredHeight(); 4442c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4452c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (showPlaybackControl && mVolumeControl.getVisibility() == View.VISIBLE) { 4462c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim height += mDividerView.getMeasuredHeight(); 4472c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4482c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4492c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim return height; 4502c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4512c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 452aaa885dc21bf5f526e1d3897e26ade96e1fae9ccJaewan Kim private void updateMediaControlVisibility(boolean showPlaybackControl) { 45392fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang // TODO: Update the top and bottom padding of the control layout according to the display 45492fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang // height. 45592fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang mDividerView.setVisibility((mVolumeControl.getVisibility() == View.VISIBLE 456aaa885dc21bf5f526e1d3897e26ade96e1fae9ccJaewan Kim && showPlaybackControl) ? View.VISIBLE : View.GONE); 45792fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang mMediaControlLayout.setVisibility((mVolumeControl.getVisibility() == View.GONE 458f8e1601db320e5bde6cb5ddcd4ecea187e3d4362Sungsoo Lim && !showPlaybackControl) ? View.GONE : View.VISIBLE); 45986dcb627078ea297c4337ed634fc3fe874e23897Jae Seo } 46086dcb627078ea297c4337ed634fc3fe874e23897Jae Seo 46186dcb627078ea297c4337ed634fc3fe874e23897Jae Seo private void updateLayoutHeight() { 46286dcb627078ea297c4337ed634fc3fe874e23897Jae Seo // We need to defer the update until the first layout has occurred, as we don't yet know the 46386dcb627078ea297c4337ed634fc3fe874e23897Jae Seo // overall visible display size in which the window this view is attached to has been 46486dcb627078ea297c4337ed634fc3fe874e23897Jae Seo // positioned in. 46586dcb627078ea297c4337ed634fc3fe874e23897Jae Seo ViewTreeObserver observer = mDefaultControlLayout.getViewTreeObserver(); 46686dcb627078ea297c4337ed634fc3fe874e23897Jae Seo observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 46786dcb627078ea297c4337ed634fc3fe874e23897Jae Seo @Override 46886dcb627078ea297c4337ed634fc3fe874e23897Jae Seo public void onGlobalLayout() { 46986dcb627078ea297c4337ed634fc3fe874e23897Jae Seo mDefaultControlLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this); 47086dcb627078ea297c4337ed634fc3fe874e23897Jae Seo updateLayoutHeightInternal(); 47186dcb627078ea297c4337ed634fc3fe874e23897Jae Seo } 47286dcb627078ea297c4337ed634fc3fe874e23897Jae Seo }); 47392fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang } 47492fa1536ded1a81a2b054a08d72b591a13293f99Dongwon Kang 4753fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim /** 4763fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim * Updates the height of views and hide artwork or metadata if space is limited. 4773fbf2b99dc391c331c2a816e13222a700a1f6dd5Jaewan Kim */ 47886dcb627078ea297c4337ed634fc3fe874e23897Jae Seo private void updateLayoutHeightInternal() { 4792c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (mCustomControlView != null) { 4802c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim return; 4812c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 482aaa885dc21bf5f526e1d3897e26ade96e1fae9ccJaewan Kim updateMediaControlVisibility(isPlaybackControlAvailable()); 4832c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim View decorView = getWindow().getDecorView(); 4842c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim decorView.measure( 4852c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim MeasureSpec.makeMeasureSpec(getWindow().getAttributes().width, MeasureSpec.EXACTLY), 4862c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim MeasureSpec.UNSPECIFIED); 4872c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int artViewHeight = 0; 4882c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (mArtView.getDrawable() instanceof BitmapDrawable) { 4892c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim Bitmap art = ((BitmapDrawable) mArtView.getDrawable()).getBitmap(); 4902c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (art != null) { 4912c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim artViewHeight = getDesiredArtHeight(art.getWidth(), art.getHeight()); 4922c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mArtView.setScaleType(art.getWidth() >= art.getHeight() 4932c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim ? ImageView.ScaleType.FIT_XY : ImageView.ScaleType.FIT_CENTER); 4942c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4952c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 4962c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int mainControllerHeight = getMainControllerHeight(isPlaybackControlAvailable()); 4972c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim int volumeGroupListCount = mVolumeGroupList.getVisibility() == View.VISIBLE 4982c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim ? mVolumeGroupList.getAdapter().getCount() : 0; 499c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim // Scale down volume group list items in landscape mode. 500c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim for (int i = 0; i < volumeGroupListCount; i++) { 501c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim View item = mVolumeGroupList.getChildAt(i); 502c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim if (item != null) { 503c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim setLayoutHeight(item, mVolumeGroupListItemHeight); 504c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim setLayoutHeight(item.findViewById(R.id.mr_volume_item_icon), 505c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim mVolumeGroupListItemIconSize); 506c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim } 507c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim } 50840181af8431b704013f596a5ac298a06174d4d82Jaewan Kim int volumeGroupHeight = (volumeGroupListCount == 0) ? 0 509c5738b858579021cc89fffd8a891b4c5ea8c0f83Jaewan Kim : mVolumeGroupListItemHeight * volumeGroupListCount + mVolumeGroupListPaddingTop; 51019d268075834665bf62567b224dcd3549c92d3c3Jae Seo volumeGroupHeight = Math.min(volumeGroupHeight, mVolumeGroupListMaxHeight); 51119d268075834665bf62567b224dcd3549c92d3c3Jae Seo 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 } 541aaa885dc21bf5f526e1d3897e26ade96e1fae9ccJaewan Kim updateMediaControlVisibility(mPlaybackControl.getVisibility() == View.VISIBLE); 5422c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mainControllerHeight = getMainControllerHeight( 5432c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim mPlaybackControl.getVisibility() == View.VISIBLE); 5448367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim desiredControlLayoutHeight = 5452c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim Math.max(artViewHeight, volumeGroupHeight) + mainControllerHeight; 5462c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 5472c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim // Limit the volume group list height to fit the screen. 5488367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim if (desiredControlLayoutHeight > maximumControlViewHeight) { 5498367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim volumeGroupHeight -= (desiredControlLayoutHeight - maximumControlViewHeight); 5508367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim desiredControlLayoutHeight = maximumControlViewHeight; 5512c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5522c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim setLayoutHeight(mVolumeGroupList, volumeGroupHeight); 5538367dca195f881c38fbaf69a5d533a6cca820471Jaewan Kim setLayoutHeight(mDefaultControlLayout, desiredControlLayoutHeight); 5542c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim } 5552c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim 5561ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private void updateVolumeControl() { 5571ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (!mVolumeSliderTouched) { 5587447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim if (isVolumeControlAvailable(mRoute)) { 5591ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeControl.setVisibility(View.VISIBLE); 5601ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeSlider.setMax(mRoute.getVolumeMax()); 5611ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeSlider.setProgress(mRoute.getVolume()); 562050b7ec33bd9a2fe493f0b0b85d49ed213046219Jae Seo if (getGroup() == null) { 563050b7ec33bd9a2fe493f0b0b85d49ed213046219Jae Seo mGroupExpandCollapseButton.setVisibility(View.GONE); 564050b7ec33bd9a2fe493f0b0b85d49ed213046219Jae Seo } else { 565050b7ec33bd9a2fe493f0b0b85d49ed213046219Jae Seo mGroupExpandCollapseButton.setVisibility(View.VISIBLE); 566050b7ec33bd9a2fe493f0b0b85d49ed213046219Jae Seo VolumeGroupAdapter adapter = 567050b7ec33bd9a2fe493f0b0b85d49ed213046219Jae Seo (VolumeGroupAdapter) mVolumeGroupList.getAdapter(); 568050b7ec33bd9a2fe493f0b0b85d49ed213046219Jae Seo if (adapter != null) { 569050b7ec33bd9a2fe493f0b0b85d49ed213046219Jae Seo adapter.notifyDataSetChanged(); 5701ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 5711ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 5721ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 5731ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mVolumeControl.setVisibility(View.GONE); 5741ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 5752c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim updateLayoutHeight(); 5767447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim } else if (mVolumeControl.getVisibility() == View.VISIBLE) { 5777447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim mVolumeSlider.setProgress(mRoute.getVolume()); 5787447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim if (mIsGroupExpanded) { 5797447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim for (int i = 0; i < mVolumeGroupList.getChildCount(); ++i) { 5807447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim MediaRouter.RouteInfo route = getGroup().getRouteAt(i); 5817447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim if (isVolumeControlAvailable(route)) { 5827447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim SeekBar volumeSlider = (SeekBar) mVolumeGroupList.getChildAt(i) 5837447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim .findViewById(R.id.mr_volume_slider); 5847447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim volumeSlider.setProgress(route.getVolume()); 5857447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim } 5867447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim } 5877447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim } 5881ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 5891ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 5901ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 5911ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim private void updatePlaybackControl() { 5922c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim if (isPlaybackControlAvailable()) { 5931ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim CharSequence title = mDescription == null ? null : mDescription.getTitle(); 5941ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean hasTitle = !TextUtils.isEmpty(title); 5951ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 5961ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim CharSequence subtitle = mDescription == null ? null : mDescription.getSubtitle(); 5971ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean hasSubtitle = !TextUtils.isEmpty(subtitle); 5981ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim 5998fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang boolean showTitle = false; 6008fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang boolean showSubtitle = false; 6018fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang if (mRoute.getPresentationDisplayId() 6028fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang != MediaRouter.RouteInfo.PRESENTATION_DISPLAY_ID_NONE) { 6038fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang // The user is currently casting screen. 6048fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mTitleView.setText(R.string.mr_controller_casting_screen); 6058fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang showTitle = true; 6068fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang } else if (mState == null || mState.getState() == PlaybackStateCompat.STATE_NONE) { 6078fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mTitleView.setText(R.string.mr_controller_no_media_selected); 6088fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang showTitle = true; 6098fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang } else if (!hasTitle && !hasSubtitle) { 6108fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mTitleView.setText(R.string.mr_controller_no_info_available); 6118fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang showTitle = true; 6121ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 6138fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang if (hasTitle) { 6148fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mTitleView.setText(title); 6158fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang showTitle = true; 6168fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang } 6178fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang if (hasSubtitle) { 6188fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mSubtitleView.setText(subtitle); 6198fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang showSubtitle = true; 6208fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang } 6211ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 6228fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mTitleView.setVisibility(showTitle ? View.VISIBLE : View.GONE); 6238fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang mSubtitleView.setVisibility(showSubtitle ? View.VISIBLE : View.GONE); 6248fd7b051e85d46381b5b8afd3d4b569d155ac48eInsun Kang 6251ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (mState != null) { 6261ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean isPlaying = mState.getState() == PlaybackStateCompat.STATE_BUFFERING 6271ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim || mState.getState() == PlaybackStateCompat.STATE_PLAYING; 6281ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean supportsPlay = (mState.getActions() & (PlaybackStateCompat.ACTION_PLAY 6291ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0; 6301ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim boolean supportsPause = (mState.getActions() & (PlaybackStateCompat.ACTION_PAUSE 6311ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim | PlaybackStateCompat.ACTION_PLAY_PAUSE)) != 0; 6321ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim if (isPlaying && supportsPause) { 6331ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setVisibility(View.VISIBLE); 6341ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setImageResource(MediaRouterThemeHelper.getThemeResource( 6351ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim getContext(), R.attr.mediaRoutePauseDrawable)); 6361ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setContentDescription(getContext().getResources() 6371ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim .getText(R.string.mr_controller_pause)); 6381ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else if (!isPlaying && supportsPlay) { 6391ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setVisibility(View.VISIBLE); 6401ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setImageResource(MediaRouterThemeHelper.getThemeResource( 6411ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim getContext(), R.attr.mediaRoutePlayDrawable)); 6421ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setContentDescription(getContext().getResources() 6431ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim .getText(R.string.mr_controller_play)); 6441ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else { 6451ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim mPlayPauseButton.setVisibility(View.GONE); 6461ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 6471ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 6481ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } 6492c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim updateLayoutHeight(); 6502b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang } 6512b274bd3e06bd33c9b2a0851256afcda94d96395Dongwon Kang 6527447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim private boolean isVolumeControlAvailable(MediaRouter.RouteInfo route) { 6537447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim return mVolumeControlEnabled && route.getVolumeHandling() 6547447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim == MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE; 655f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah } 656f1ca2f34f5efed21a49d92dd06e8e51be104c10bPrameet Shah 657be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang private static void setLayoutHeight(View view, int height) { 658be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang ViewGroup.LayoutParams lp = view.getLayoutParams(); 659be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang lp.height = height; 660be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang view.setLayoutParams(lp); 661be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang } 662be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang 66313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim /** 66413d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim * Returns desired art height to fit into controller dialog. 66513d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim */ 66613d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim private int getDesiredArtHeight(int originalWidth, int originalHeight) { 66713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim if (originalWidth >= originalHeight) { 66813d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // For landscape art, fit width to dialog width. 669f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo return (int) ((float) mDialogContentWidth * originalHeight / originalWidth + 0.5f); 67013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim } 67113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // For portrait art, fit height to 16:9 ratio case's height. 672f4575634e9f3c2b61c2e6bceaeed6cabb378803fJae Seo return (int) ((float) mDialogContentWidth * 9 / 16 + 0.5f); 67313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim } 67413d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim 67511417b1cfde8f1749905f2d735623af9214148afJeff Brown private final class MediaRouterCallback extends MediaRouter.Callback { 67611417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 67711417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route) { 67811417b1cfde8f1749905f2d735623af9214148afJeff Brown update(); 67911417b1cfde8f1749905f2d735623af9214148afJeff Brown } 68011417b1cfde8f1749905f2d735623af9214148afJeff Brown 68111417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 68211417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo route) { 68311417b1cfde8f1749905f2d735623af9214148afJeff Brown update(); 68411417b1cfde8f1749905f2d735623af9214148afJeff Brown } 68511417b1cfde8f1749905f2d735623af9214148afJeff Brown 68611417b1cfde8f1749905f2d735623af9214148afJeff Brown @Override 68711417b1cfde8f1749905f2d735623af9214148afJeff Brown public void onRouteVolumeChanged(MediaRouter router, MediaRouter.RouteInfo route) { 68811417b1cfde8f1749905f2d735623af9214148afJeff Brown if (route == mRoute) { 6891ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim updateVolumeControl(); 69094be6100218126ce6a08bf1f56209578500b361fRoboErik } 69194be6100218126ce6a08bf1f56209578500b361fRoboErik } 69294be6100218126ce6a08bf1f56209578500b361fRoboErik } 69394be6100218126ce6a08bf1f56209578500b361fRoboErik 69494be6100218126ce6a08bf1f56209578500b361fRoboErik private final class MediaControllerCallback extends MediaControllerCompat.Callback { 69594be6100218126ce6a08bf1f56209578500b361fRoboErik @Override 69694be6100218126ce6a08bf1f56209578500b361fRoboErik public void onSessionDestroyed() { 69794be6100218126ce6a08bf1f56209578500b361fRoboErik if (mMediaController != null) { 69894be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.unregisterCallback(mControllerCallback); 69994be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController = null; 70094be6100218126ce6a08bf1f56209578500b361fRoboErik } 70194be6100218126ce6a08bf1f56209578500b361fRoboErik } 70294be6100218126ce6a08bf1f56209578500b361fRoboErik 70394be6100218126ce6a08bf1f56209578500b361fRoboErik @Override 70494be6100218126ce6a08bf1f56209578500b361fRoboErik public void onPlaybackStateChanged(PlaybackStateCompat state) { 70594be6100218126ce6a08bf1f56209578500b361fRoboErik mState = state; 70694be6100218126ce6a08bf1f56209578500b361fRoboErik update(); 70794be6100218126ce6a08bf1f56209578500b361fRoboErik } 70894be6100218126ce6a08bf1f56209578500b361fRoboErik 70994be6100218126ce6a08bf1f56209578500b361fRoboErik @Override 71094be6100218126ce6a08bf1f56209578500b361fRoboErik public void onMetadataChanged(MediaMetadataCompat metadata) { 71194be6100218126ce6a08bf1f56209578500b361fRoboErik mDescription = metadata == null ? null : metadata.getDescription(); 71294be6100218126ce6a08bf1f56209578500b361fRoboErik update(); 71394be6100218126ce6a08bf1f56209578500b361fRoboErik } 71494be6100218126ce6a08bf1f56209578500b361fRoboErik } 71594be6100218126ce6a08bf1f56209578500b361fRoboErik 71694be6100218126ce6a08bf1f56209578500b361fRoboErik private final class ClickListener implements View.OnClickListener { 71794be6100218126ce6a08bf1f56209578500b361fRoboErik @Override 71894be6100218126ce6a08bf1f56209578500b361fRoboErik public void onClick(View v) { 71994be6100218126ce6a08bf1f56209578500b361fRoboErik int id = v.getId(); 72006991009e52024cbb3dde550988e06149e77a269Jae Seo if (id == BUTTON_STOP_RES_ID || id == BUTTON_DISCONNECT_RES_ID) { 72194be6100218126ce6a08bf1f56209578500b361fRoboErik if (mRoute.isSelected()) { 72206991009e52024cbb3dde550988e06149e77a269Jae Seo mRouter.unselect(id == BUTTON_STOP_RES_ID ? 72394be6100218126ce6a08bf1f56209578500b361fRoboErik MediaRouter.UNSELECT_REASON_STOPPED : 72494be6100218126ce6a08bf1f56209578500b361fRoboErik MediaRouter.UNSELECT_REASON_DISCONNECTED); 72594be6100218126ce6a08bf1f56209578500b361fRoboErik } 72694be6100218126ce6a08bf1f56209578500b361fRoboErik dismiss(); 7277ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim } else if (id == R.id.mr_control_play_pause) { 72894be6100218126ce6a08bf1f56209578500b361fRoboErik if (mMediaController != null && mState != null) { 729ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo boolean isPlaying = mState.getState() == PlaybackStateCompat.STATE_PLAYING; 730ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo if (isPlaying) { 73194be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.getTransportControls().pause(); 73294be6100218126ce6a08bf1f56209578500b361fRoboErik } else { 73394be6100218126ce6a08bf1f56209578500b361fRoboErik mMediaController.getTransportControls().play(); 73494be6100218126ce6a08bf1f56209578500b361fRoboErik } 735ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo // Announce the action for accessibility. 736ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo if (mAccessibilityManager != null && mAccessibilityManager.isEnabled()) { 737ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo AccessibilityEvent event = AccessibilityEvent.obtain( 738ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo AccessibilityEventCompat.TYPE_ANNOUNCEMENT); 739ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo event.setPackageName(getContext().getPackageName()); 740ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo event.setClassName(getClass().getName()); 741ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo int resId = isPlaying ? 742ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo R.string.mr_controller_pause : R.string.mr_controller_play; 743ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo event.getText().add(getContext().getString(resId)); 744ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo mAccessibilityManager.sendAccessibilityEvent(event); 745ee7ae661b02471fe598566b1e90adbacda240b0bJae Seo } 74694be6100218126ce6a08bf1f56209578500b361fRoboErik } 7471ce169ba80c2047846dca5ee8c723faadcd1da86Sungsoo Lim } else if (id == R.id.mr_close) { 748b48ccf48b0281e69262fc643d0def898aede407bSungsoo Lim dismiss(); 74911417b1cfde8f1749905f2d735623af9214148afJeff Brown } 75011417b1cfde8f1749905f2d735623af9214148afJeff Brown } 75111417b1cfde8f1749905f2d735623af9214148afJeff Brown } 752005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 753435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim private class VolumeChangeListener implements OnSeekBarChangeListener { 754435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim private final Runnable mStopTrackingTouch = new Runnable() { 7556051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo @Override 756435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim public void run() { 757435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim if (mVolumeSliderTouched) { 758435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeSliderTouched = false; 759435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim updateVolumeControl(); 7606051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 7616051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 762435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim }; 7636051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 764435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim @Override 765435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim public void onStartTrackingTouch(SeekBar seekBar) { 766435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim if (mVolumeSliderTouched) { 767435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeSlider.removeCallbacks(mStopTrackingTouch); 768435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } else { 769435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeSliderTouched = true; 7706051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 771435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } 7726051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 773435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim @Override 774435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim public void onStopTrackingTouch(SeekBar seekBar) { 775435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim // Defer resetting mVolumeSliderTouched to allow the media route provider 776435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim // a little time to settle into its new state and publish the final 777435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim // volume update. 778435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mVolumeSlider.postDelayed(mStopTrackingTouch, VOLUME_UPDATE_DELAY_MILLIS); 779435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } 780435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim 781435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim @Override 782435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 783435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim if (fromUser) { 784435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim int tag = (int) seekBar.getTag(); 785435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim if (tag == VOLUME_SLIDER_TAG_MASTER) { 786435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim mRoute.requestSetVolume(progress); 787435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } else if (tag - VOLUME_SLIDER_TAG_BASE >= 0 788435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim && tag - VOLUME_SLIDER_TAG_BASE < getGroup().getRouteCount()) { 789435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim getGroup().getRouteAt(tag - VOLUME_SLIDER_TAG_BASE).requestSetVolume(progress); 790435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } 7916051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 792435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } 793435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim } 794435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim 795435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim private class VolumeGroupAdapter extends ArrayAdapter<MediaRouter.RouteInfo> { 796435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim final static float DISABLED_ALPHA = .3f; 7976051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 7986051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo public VolumeGroupAdapter(Context context, List<MediaRouter.RouteInfo> objects) { 7996051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo super(context, 0, objects); 8006051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 8016051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 8026051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo @Override 8036051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo public View getView(final int position, View convertView, ViewGroup parent) { 8046051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo View v = convertView; 8056051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo if (v == null) { 8066051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo v = LayoutInflater.from(getContext()).inflate( 8072c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim R.layout.mr_controller_volume_item, parent, false); 8086051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 80919d268075834665bf62567b224dcd3549c92d3c3Jae Seo 8106051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo MediaRouter.RouteInfo route = getItem(position); 8116051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo if (route != null) { 8120e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo boolean isEnabled = route.isEnabled(); 8130e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo 8147ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim TextView routeName = (TextView) v.findViewById(R.id.mr_name); 8150e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo routeName.setEnabled(isEnabled); 8160e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo routeName.setText(route.getName()); 8176051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 818ea15dd5d0313d55452f552d8583eb230b2c9506fJaewan Kim MediaRouteVolumeSlider volumeSlider = 819ea15dd5d0313d55452f552d8583eb230b2c9506fJaewan Kim (MediaRouteVolumeSlider) v.findViewById(R.id.mr_volume_slider); 820435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim volumeSlider.setTag(VOLUME_SLIDER_TAG_BASE + position); 821ea15dd5d0313d55452f552d8583eb230b2c9506fJaewan Kim volumeSlider.setShowThumb(isEnabled); 8220e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo if (isEnabled) { 8237447b1958129579090ee279caac7d703dba2ad28Sungsoo Lim if (isVolumeControlAvailable(route)) { 8240e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setMax(route.getVolumeMax()); 8250e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setProgress(route.getVolume()); 826435661b8ed5ba59ef5d78cf10fbbf005bf62b895Sungsoo Lim volumeSlider.setOnSeekBarChangeListener(mVolumeChangeListener); 827ea15dd5d0313d55452f552d8583eb230b2c9506fJaewan Kim volumeSlider.setEnabled(true); 8280e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo } else { 8290e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setMax(100); 8300e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setProgress(100); 8310e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo volumeSlider.setEnabled(false); 8320e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo } 8330e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo } 8340e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo 8350e36aa71ffed511f5ad6b0a24e75ccf651e43c40Jae Seo ImageView volumeItemIcon = 8367ff59b631bd798bdf0c6647d1279a08a33c62977Sungsoo Lim (ImageView) v.findViewById(R.id.mr_volume_item_icon); 83777367b4a1871417198d0399d9ad074314c758567Jae Seo volumeItemIcon.setAlpha(isEnabled ? 255 : (int) (255 * DISABLED_ALPHA)); 8386051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 8396051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo return v; 8406051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 8416051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo } 8426051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo 843005482649154d0970693b3967241eb4d2cb22003Jaewan Kim private class FetchArtTask extends AsyncTask<Void, Void, Bitmap> { 8448bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo final Bitmap mIconBitmap; 8458bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo final Uri mIconUri; 8468bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo int mBackgroundColor; 8478bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo 8488bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo FetchArtTask() { 8498bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mIconBitmap = mDescription == null ? null : mDescription.getIconBitmap(); 8508bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mIconUri = mDescription == null ? null : mDescription.getIconUri(); 8518bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } 8528bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo 8538bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo @Override 8548bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo protected void onPreExecute() { 8558bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo if (mArtIconBitmap == mIconBitmap && mArtIconUri == mIconUri) { 8568bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo // Already handled the current art. 8578bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo cancel(true); 8588bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } 8598bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } 860005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 861005482649154d0970693b3967241eb4d2cb22003Jaewan Kim @Override 862005482649154d0970693b3967241eb4d2cb22003Jaewan Kim protected Bitmap doInBackground(Void... arg) { 86313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim Bitmap art = null; 8648bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo if (mIconBitmap != null) { 8658bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo art = mIconBitmap; 8668bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } else if (mIconUri != null) { 8678bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo String scheme = mIconUri.getScheme(); 868005482649154d0970693b3967241eb4d2cb22003Jaewan Kim if (!(ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme) 869005482649154d0970693b3967241eb4d2cb22003Jaewan Kim || ContentResolver.SCHEME_CONTENT.equals(scheme) 870005482649154d0970693b3967241eb4d2cb22003Jaewan Kim || ContentResolver.SCHEME_FILE.equals(scheme))) { 871005482649154d0970693b3967241eb4d2cb22003Jaewan Kim Log.w(TAG, "Icon Uri should point to local resources."); 872005482649154d0970693b3967241eb4d2cb22003Jaewan Kim return null; 873005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 874005482649154d0970693b3967241eb4d2cb22003Jaewan Kim BufferedInputStream stream = null; 875005482649154d0970693b3967241eb4d2cb22003Jaewan Kim try { 876005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream = new BufferedInputStream( 8778bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo getContext().getContentResolver().openInputStream(mIconUri)); 878005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 87913d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // Query art size. 880005482649154d0970693b3967241eb4d2cb22003Jaewan Kim BitmapFactory.Options options = new BitmapFactory.Options(); 881005482649154d0970693b3967241eb4d2cb22003Jaewan Kim options.inJustDecodeBounds = true; 882005482649154d0970693b3967241eb4d2cb22003Jaewan Kim BitmapFactory.decodeStream(stream, null, options); 88313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim if (options.outWidth == 0 || options.outHeight == 0) { 88413d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim return null; 88513d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim } 88613d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // Rewind the stream in order to restart art decoding. 887005482649154d0970693b3967241eb4d2cb22003Jaewan Kim try { 888005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream.reset(); 889005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } catch (IOException e) { 890005482649154d0970693b3967241eb4d2cb22003Jaewan Kim // Failed to rewind the stream, try to reopen it. 891005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream.close(); 892005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream = new BufferedInputStream(getContext().getContentResolver() 8938bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo .openInputStream(mIconUri)); 894005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 89513d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim // Calculate required size to decode the art and possibly resize it. 896005482649154d0970693b3967241eb4d2cb22003Jaewan Kim options.inJustDecodeBounds = false; 89713d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim int reqHeight = getDesiredArtHeight(options.outWidth, options.outHeight); 89813d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim int ratio = options.outHeight / reqHeight; 899005482649154d0970693b3967241eb4d2cb22003Jaewan Kim options.inSampleSize = Math.max(1, Integer.highestOneBit(ratio)); 900005482649154d0970693b3967241eb4d2cb22003Jaewan Kim if (isCancelled()) { 901005482649154d0970693b3967241eb4d2cb22003Jaewan Kim return null; 902005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 90313d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim art = BitmapFactory.decodeStream(stream, null, options); 904005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } catch (IOException e){ 9058bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo Log.w(TAG, "Unable to open: " + mIconUri, e); 906005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } finally { 907005482649154d0970693b3967241eb4d2cb22003Jaewan Kim if (stream != null) { 908005482649154d0970693b3967241eb4d2cb22003Jaewan Kim try { 909005482649154d0970693b3967241eb4d2cb22003Jaewan Kim stream.close(); 910005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } catch (IOException e) { 911005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 912005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 913005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 914005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 915145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim if (art != null && art.getWidth() < art.getHeight()) { 916c4c371f91673a882177f16fa95723e7e69f54882Insun Kang // Portrait art requires dominant color as background color. 917145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim Palette palette = new Palette.Builder(art).maximumColorCount(1).generate(); 918be6358a7c928a09f2c767524299f86a8aad84558Dongwon Kang mBackgroundColor = palette.getSwatches().isEmpty() 919145e93b13dd025b278665494e7be0c15b8df5986Jaewan Kim ? 0 : palette.getSwatches().get(0).getRgb(); 920005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 92113d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim return art; 922005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 923005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 924005482649154d0970693b3967241eb4d2cb22003Jaewan Kim @Override 925005482649154d0970693b3967241eb4d2cb22003Jaewan Kim protected void onCancelled() { 926005482649154d0970693b3967241eb4d2cb22003Jaewan Kim mFetchArtTask = null; 927005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 928005482649154d0970693b3967241eb4d2cb22003Jaewan Kim 929005482649154d0970693b3967241eb4d2cb22003Jaewan Kim @Override 93013d6fb598d2270bed0dbcdb8d66d012382780f53Jaewan Kim protected void onPostExecute(Bitmap art) { 931005482649154d0970693b3967241eb4d2cb22003Jaewan Kim mFetchArtTask = null; 9328bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo if (mArtIconBitmap != mIconBitmap || mArtIconUri != mIconUri) { 9338bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mArtIconBitmap = mIconBitmap; 9348bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mArtIconUri = mIconUri; 9358bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo 9368bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mArtView.setImageBitmap(art); 9378bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo mArtView.setBackgroundColor(mBackgroundColor); 9382c8c38b6c0d4302b4a6537b972c905c4fc8dd3e0Jaewan Kim updateLayoutHeight(); 9398bc60d9260a4b31356fceb31264a47b55f6114f4Jae Seo } 940005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 941005482649154d0970693b3967241eb4d2cb22003Jaewan Kim } 9426051d8374c90da4826698b66ed7cb13ebc2c65bfJae Seo} 943