MediaRouteControllerDialog.java revision d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0
1692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim/* 2692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Copyright 2018 The Android Open Source Project 3692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * 4692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Licensed under the Apache License, Version 2.0 (the "License"); 5692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * you may not use this file except in compliance with the License. 6692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * You may obtain a copy of the License at 7692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * 8692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * http://www.apache.org/licenses/LICENSE-2.0 9692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * 10692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Unless required by applicable law or agreed to in writing, software 11692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * distributed under the License is distributed on an "AS IS" BASIS, 12692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * See the License for the specific language governing permissions and 14692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * limitations under the License. 15692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 16692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 17692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limpackage com.android.support.mediarouter.app; 18692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 19692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport static android.support.v4.media.session.PlaybackStateCompat.ACTION_PAUSE; 20692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport static android.support.v4.media.session.PlaybackStateCompat.ACTION_PLAY; 21692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport static android.support.v4.media.session.PlaybackStateCompat.ACTION_PLAY_PAUSE; 22692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport static android.support.v4.media.session.PlaybackStateCompat.ACTION_STOP; 23692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 24d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Limimport android.app.AlertDialog; 25692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.app.PendingIntent; 26692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.content.ContentResolver; 27692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.content.Context; 28692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.content.res.Resources; 29692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.graphics.Bitmap; 30692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.graphics.BitmapFactory; 31692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.graphics.Rect; 32692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.graphics.drawable.BitmapDrawable; 33692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.net.Uri; 34692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.os.AsyncTask; 35692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.os.Bundle; 36692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.os.RemoteException; 37692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.os.SystemClock; 38692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.support.v4.media.MediaDescriptionCompat; 39692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.support.v4.media.MediaMetadataCompat; 40692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.support.v4.media.session.MediaControllerCompat; 41692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.support.v4.media.session.MediaSessionCompat; 42692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.support.v4.media.session.PlaybackStateCompat; 43692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.support.v4.util.ObjectsCompat; 44692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.support.v4.view.accessibility.AccessibilityEventCompat; 45692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.support.v7.graphics.Palette; 46692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.text.TextUtils; 47692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.util.Log; 48d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Limimport android.view.ContextThemeWrapper; 49692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.view.KeyEvent; 50692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.view.LayoutInflater; 51692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.view.View; 52692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.view.View.MeasureSpec; 53692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.view.ViewGroup; 54692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.view.ViewTreeObserver; 55692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.view.accessibility.AccessibilityEvent; 56692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.view.accessibility.AccessibilityManager; 57692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.view.animation.AccelerateDecelerateInterpolator; 58692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.view.animation.AlphaAnimation; 59692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.view.animation.Animation; 60692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.view.animation.AnimationSet; 61692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.view.animation.AnimationUtils; 62692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.view.animation.Interpolator; 63692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.view.animation.Transformation; 64692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.view.animation.TranslateAnimation; 65692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.widget.ArrayAdapter; 66692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.widget.Button; 67692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.widget.FrameLayout; 68692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.widget.ImageButton; 69692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.widget.ImageView; 70692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.widget.LinearLayout; 71692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.widget.RelativeLayout; 72692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.widget.SeekBar; 73692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport android.widget.TextView; 74692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 75d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Limimport com.android.media.update.ApiHelper; 76692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport com.android.media.update.R; 77692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport com.android.support.mediarouter.media.MediaRouteSelector; 78692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport com.android.support.mediarouter.media.MediaRouter; 79692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport com.android.support.mediarouter.app.OverlayListView.OverlayObject; 80692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 81692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.io.BufferedInputStream; 82692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.io.IOException; 83692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.io.InputStream; 84692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.net.URL; 85692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.net.URLConnection; 86692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.util.ArrayList; 87692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.util.HashMap; 88692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.util.HashSet; 89692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.util.List; 90692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.util.Map; 91692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.util.Set; 92692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limimport java.util.concurrent.TimeUnit; 93692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 94692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim/** 95692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * This class implements the route controller dialog for {@link MediaRouter}. 96692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * <p> 97692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * This dialog allows the user to control or disconnect from the currently selected route. 98692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * </p> 99692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * 100692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * @see MediaRouteButton 101692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * @see MediaRouteActionProvider 102692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 103692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Limpublic class MediaRouteControllerDialog extends AlertDialog { 104692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Tags should be less than 24 characters long (see docs for android.util.Log.isLoggable()) 105692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim static final String TAG = "MediaRouteCtrlDialog"; 106692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 107692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 108692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Time to wait before updating the volume when the user lets go of the seek bar 109692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // to allow the route provider time to propagate the change and publish a new 110692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // route descriptor. 111692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim static final int VOLUME_UPDATE_DELAY_MILLIS = 500; 112692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim static final int CONNECTION_TIMEOUT_MILLIS = (int) TimeUnit.SECONDS.toMillis(30L); 113692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 114692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private static final int BUTTON_NEUTRAL_RES_ID = android.R.id.button3; 115692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim static final int BUTTON_DISCONNECT_RES_ID = android.R.id.button2; 116692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim static final int BUTTON_STOP_RES_ID = android.R.id.button1; 117692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 118692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim final MediaRouter mRouter; 119692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private final MediaRouterCallback mCallback; 120692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim final MediaRouter.RouteInfo mRoute; 121692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 122692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Context mContext; 123692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private boolean mCreated; 124692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private boolean mAttachedToWindow; 125692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 126692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private int mDialogContentWidth; 127692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 128692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private View mCustomControlView; 129692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 130692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private Button mDisconnectButton; 131692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private Button mStopCastingButton; 132692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private ImageButton mPlaybackControlButton; 133692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private ImageButton mCloseButton; 134692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private MediaRouteExpandCollapseButton mGroupExpandCollapseButton; 135692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 136692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private FrameLayout mExpandableAreaLayout; 137692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private LinearLayout mDialogAreaLayout; 138692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim FrameLayout mDefaultControlLayout; 139692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private FrameLayout mCustomControlLayout; 140692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private ImageView mArtView; 141692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private TextView mTitleView; 142692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private TextView mSubtitleView; 143692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private TextView mRouteNameTextView; 144692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 145692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private boolean mVolumeControlEnabled = true; 146692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Layout for media controllers including play/pause button and the main volume slider. 147692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private LinearLayout mMediaMainControlLayout; 148692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private RelativeLayout mPlaybackControlLayout; 149692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private LinearLayout mVolumeControlLayout; 150692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private View mDividerView; 151692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 152692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim OverlayListView mVolumeGroupList; 153692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim VolumeGroupAdapter mVolumeGroupAdapter; 154692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private List<MediaRouter.RouteInfo> mGroupMemberRoutes; 155692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Set<MediaRouter.RouteInfo> mGroupMemberRoutesAdded; 156692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private Set<MediaRouter.RouteInfo> mGroupMemberRoutesRemoved; 157692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Set<MediaRouter.RouteInfo> mGroupMemberRoutesAnimatingWithBitmap; 158692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim SeekBar mVolumeSlider; 159692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim VolumeChangeListener mVolumeChangeListener; 160692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouter.RouteInfo mRouteInVolumeSliderTouched; 161692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private int mVolumeGroupListItemIconSize; 162692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private int mVolumeGroupListItemHeight; 163692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private int mVolumeGroupListMaxHeight; 164692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private final int mVolumeGroupListPaddingTop; 165692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Map<MediaRouter.RouteInfo, SeekBar> mVolumeSliderMap; 166692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 167692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaControllerCompat mMediaController; 168692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaControllerCallback mControllerCallback; 169692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim PlaybackStateCompat mState; 170692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaDescriptionCompat mDescription; 171692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 172692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim FetchArtTask mFetchArtTask; 173692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Bitmap mArtIconBitmap; 174692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Uri mArtIconUri; 175692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean mArtIconIsLoaded; 176692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Bitmap mArtIconLoadedBitmap; 177692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int mArtIconBackgroundColor; 178692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 179692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean mHasPendingUpdate; 180692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean mPendingUpdateAnimationNeeded; 181692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 182692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean mIsGroupExpanded; 183692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean mIsGroupListAnimating; 184692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean mIsGroupListAnimationPending; 185692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int mGroupListAnimationDurationMs; 186692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private int mGroupListFadeInDurationMs; 187692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private int mGroupListFadeOutDurationMs; 188692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 189692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private Interpolator mInterpolator; 190692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private Interpolator mLinearOutSlowInInterpolator; 191692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private Interpolator mFastOutSlowInInterpolator; 192692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private Interpolator mAccelerateDecelerateInterpolator; 193692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 194692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim final AccessibilityManager mAccessibilityManager; 195692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 196692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Runnable mGroupListFadeInAnimation = new Runnable() { 197692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 198692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void run() { 199692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim startGroupListFadeInAnimation(); 200692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 201692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim }; 202692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 203692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public MediaRouteControllerDialog(Context context) { 204692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim this(context, 0); 205692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 206692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 207692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public MediaRouteControllerDialog(Context context, int theme) { 208d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim // TODO (b/72975976): Avoid to use ContextThemeWrapper with app context and lib theme. 209d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim super(new ContextThemeWrapper(context, 210d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim ApiHelper.getLibTheme(MediaRouterThemeHelper.getRouterThemeId(context))), theme); 211692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mContext = getContext(); 212692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 213692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mControllerCallback = new MediaControllerCallback(); 214692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRouter = MediaRouter.getInstance(mContext); 215692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mCallback = new MediaRouterCallback(); 216692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRoute = mRouter.getSelectedRoute(); 217692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim setMediaSession(mRouter.getMediaSessionToken()); 218d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim mVolumeGroupListPaddingTop = ApiHelper.getLibResources().getDimensionPixelSize( 219692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim R.dimen.mr_controller_volume_group_list_padding_top); 220692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mAccessibilityManager = 221692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE); 222d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim mLinearOutSlowInInterpolator = AnimationUtils.loadInterpolator( 223d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim mContext, android.R.interpolator.linear_out_slow_in); 224d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator( 225d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim mContext, android.R.interpolator.fast_out_slow_in); 226692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mAccelerateDecelerateInterpolator = new AccelerateDecelerateInterpolator(); 227692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 228692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 229692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 230692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Gets the route that this dialog is controlling. 231692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 232692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public MediaRouter.RouteInfo getRoute() { 233692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return mRoute; 234692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 235692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 236692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private MediaRouter.RouteGroup getGroup() { 237692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mRoute instanceof MediaRouter.RouteGroup) { 238692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return (MediaRouter.RouteGroup) mRoute; 239692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 240692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return null; 241692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 242692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 243692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 244692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Provides the subclass an opportunity to create a view that will replace the default media 245692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * controls for the currently playing content. 246692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * 247692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * @param savedInstanceState The dialog's saved instance state. 248692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * @return The media control view, or null if none. 249692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 250692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public View onCreateMediaControlView(Bundle savedInstanceState) { 251692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return null; 252692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 253692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 254692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 255692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Gets the media control view that was created by {@link #onCreateMediaControlView(Bundle)}. 256692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * 257692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * @return The media control view, or null if none. 258692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 259692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public View getMediaControlView() { 260692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return mCustomControlView; 261692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 262692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 263692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 264692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Sets whether to enable the volume slider and volume control using the volume keys 265692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * when the route supports it. 266692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * <p> 267692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * The default value is true. 268692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * </p> 269692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 270692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void setVolumeControlEnabled(boolean enable) { 271692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mVolumeControlEnabled != enable) { 272692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeControlEnabled = enable; 273692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mCreated) { 274692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim update(false); 275692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 276692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 277692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 278692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 279692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 280692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Returns whether to enable the volume slider and volume control using the volume keys 281692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * when the route supports it. 282692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 283692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public boolean isVolumeControlEnabled() { 284692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return mVolumeControlEnabled; 285692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 286692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 287692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 288692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Set the session to use for metadata and transport controls. The dialog 289692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * will listen to changes on this session and update the UI automatically in 290692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * response to changes. 291692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * 292692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * @param sessionToken The token for the session to use. 293692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 294692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private void setMediaSession(MediaSessionCompat.Token sessionToken) { 295692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mMediaController != null) { 296692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mMediaController.unregisterCallback(mControllerCallback); 297692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mMediaController = null; 298692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 299692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (sessionToken == null) { 300692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return; 301692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 302692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (!mAttachedToWindow) { 303692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return; 304692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 305692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim try { 306692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mMediaController = new MediaControllerCompat(mContext, sessionToken); 307692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } catch (RemoteException e) { 308692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Log.e(TAG, "Error creating media controller in setMediaSession.", e); 309692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 310692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mMediaController != null) { 311692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mMediaController.registerCallback(mControllerCallback); 312692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 313692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaMetadataCompat metadata = mMediaController == null ? null 314692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim : mMediaController.getMetadata(); 315692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mDescription = metadata == null ? null : metadata.getDescription(); 316692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mState = mMediaController == null ? null : mMediaController.getPlaybackState(); 317692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim updateArtIconIfNeeded(); 318692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim update(false); 319692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 320692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 321692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 322692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Gets the session to use for metadata and transport controls. 323692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * 324692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * @return The token for the session to use or null if none. 325692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 326692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public MediaSessionCompat.Token getMediaSession() { 327692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return mMediaController == null ? null : mMediaController.getSessionToken(); 328692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 329692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 330692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 331692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim protected void onCreate(Bundle savedInstanceState) { 332692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim super.onCreate(savedInstanceState); 333692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 334692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim getWindow().setBackgroundDrawableResource(android.R.color.transparent); 335d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim 336d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim setContentView(ApiHelper.inflateLibLayout(mContext, 337d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim ApiHelper.getLibTheme(MediaRouterThemeHelper.getRouterThemeId(mContext)), 338d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim R.layout.mr_controller_material_dialog_b)); 339692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 340692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Remove the neutral button. 341692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim findViewById(BUTTON_NEUTRAL_RES_ID).setVisibility(View.GONE); 342692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 343692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ClickListener listener = new ClickListener(); 344692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 345692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mExpandableAreaLayout = findViewById(R.id.mr_expandable_area); 346692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mExpandableAreaLayout.setOnClickListener(new View.OnClickListener() { 347692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 348692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onClick(View v) { 349692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim dismiss(); 350692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 351692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim }); 352692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mDialogAreaLayout = findViewById(R.id.mr_dialog_area); 353692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mDialogAreaLayout.setOnClickListener(new View.OnClickListener() { 354692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 355692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onClick(View v) { 356692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Eat unhandled touch events. 357692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 358692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim }); 359692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int color = MediaRouterThemeHelper.getButtonTextColor(mContext); 360692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mDisconnectButton = findViewById(BUTTON_DISCONNECT_RES_ID); 361d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim mDisconnectButton.setText( 362d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim ApiHelper.getLibResources().getString(R.string.mr_controller_disconnect)); 363692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mDisconnectButton.setTextColor(color); 364692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mDisconnectButton.setOnClickListener(listener); 365692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 366692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mStopCastingButton = findViewById(BUTTON_STOP_RES_ID); 367d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim mStopCastingButton.setText( 368d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim ApiHelper.getLibResources().getString(R.string.mr_controller_stop_casting)); 369692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mStopCastingButton.setTextColor(color); 370692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mStopCastingButton.setOnClickListener(listener); 371692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 372692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRouteNameTextView = findViewById(R.id.mr_name); 373692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mCloseButton = findViewById(R.id.mr_close); 374692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mCloseButton.setOnClickListener(listener); 375692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mCustomControlLayout = findViewById(R.id.mr_custom_control); 376692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mDefaultControlLayout = findViewById(R.id.mr_default_control); 377692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 378692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Start the session activity when a content item (album art, title or subtitle) is clicked. 379692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim View.OnClickListener onClickListener = new View.OnClickListener() { 380692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 381692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onClick(View v) { 382692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mMediaController != null) { 383692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim PendingIntent pi = mMediaController.getSessionActivity(); 384692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (pi != null) { 385692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim try { 386692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim pi.send(); 387692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim dismiss(); 388692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } catch (PendingIntent.CanceledException e) { 389692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Log.e(TAG, pi + " was not sent, it had been canceled."); 390692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 391692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 392692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 393692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 394692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim }; 395692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtView = findViewById(R.id.mr_art); 396692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtView.setOnClickListener(onClickListener); 397692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim findViewById(R.id.mr_control_title_container).setOnClickListener(onClickListener); 398692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 399692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mMediaMainControlLayout = findViewById(R.id.mr_media_main_control); 400692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mDividerView = findViewById(R.id.mr_control_divider); 401692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 402692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mPlaybackControlLayout = findViewById(R.id.mr_playback_control); 403692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mTitleView = findViewById(R.id.mr_control_title); 404692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mSubtitleView = findViewById(R.id.mr_control_subtitle); 405692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mPlaybackControlButton = findViewById(R.id.mr_control_playback_ctrl); 406692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mPlaybackControlButton.setOnClickListener(listener); 407692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 408692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeControlLayout = findViewById(R.id.mr_volume_control); 409692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeControlLayout.setVisibility(View.GONE); 410692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeSlider = findViewById(R.id.mr_volume_slider); 411692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeSlider.setTag(mRoute); 412692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeChangeListener = new VolumeChangeListener(); 413692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeSlider.setOnSeekBarChangeListener(mVolumeChangeListener); 414692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 415692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupList = findViewById(R.id.mr_volume_group_list); 416692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupMemberRoutes = new ArrayList<MediaRouter.RouteInfo>(); 417692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupAdapter = new VolumeGroupAdapter(mVolumeGroupList.getContext(), 418692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupMemberRoutes); 419692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupList.setAdapter(mVolumeGroupAdapter); 420692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupMemberRoutesAnimatingWithBitmap = new HashSet<>(); 421692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 422692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouterThemeHelper.setMediaControlsBackgroundColor(mContext, 423692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mMediaMainControlLayout, mVolumeGroupList, getGroup() != null); 424692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouterThemeHelper.setVolumeSliderColor(mContext, 425692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim (MediaRouteVolumeSlider) mVolumeSlider, mMediaMainControlLayout); 426692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeSliderMap = new HashMap<>(); 427692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeSliderMap.put(mRoute, mVolumeSlider); 428692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 429692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupExpandCollapseButton = 430692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim findViewById(R.id.mr_group_expand_collapse); 431692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupExpandCollapseButton.setOnClickListener(new View.OnClickListener() { 432692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 433692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onClick(View v) { 434692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mIsGroupExpanded = !mIsGroupExpanded; 435692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mIsGroupExpanded) { 436692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupList.setVisibility(View.VISIBLE); 437692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 438692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim loadInterpolator(); 439692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim updateLayoutHeight(true); 440692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 441692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim }); 442692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim loadInterpolator(); 443d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim mGroupListAnimationDurationMs = ApiHelper.getLibResources().getInteger( 444692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim R.integer.mr_controller_volume_group_list_animation_duration_ms); 445d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim mGroupListFadeInDurationMs = ApiHelper.getLibResources().getInteger( 446692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim R.integer.mr_controller_volume_group_list_fade_in_duration_ms); 447d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim mGroupListFadeOutDurationMs = ApiHelper.getLibResources().getInteger( 448692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim R.integer.mr_controller_volume_group_list_fade_out_duration_ms); 449692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 450692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mCustomControlView = onCreateMediaControlView(savedInstanceState); 451692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mCustomControlView != null) { 452692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mCustomControlLayout.addView(mCustomControlView); 453692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mCustomControlLayout.setVisibility(View.VISIBLE); 454692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 455692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mCreated = true; 456692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim updateLayout(); 457692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 458692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 459692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 460692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Sets the width of the dialog. Also called when configuration changes. 461692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 462692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim void updateLayout() { 4630bfa950527f7b5b44658d32346fd444073b8b6d8Sungsoo Lim int width = MediaRouteDialogHelper.getDialogWidth(); 464692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim getWindow().setLayout(width, ViewGroup.LayoutParams.WRAP_CONTENT); 465692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 466692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim View decorView = getWindow().getDecorView(); 467692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mDialogContentWidth = width - decorView.getPaddingLeft() - decorView.getPaddingRight(); 468692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 469d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim Resources res = ApiHelper.getLibResources(); 470692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupListItemIconSize = res.getDimensionPixelSize( 471692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim R.dimen.mr_controller_volume_group_list_item_icon_size); 472692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupListItemHeight = res.getDimensionPixelSize( 473692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim R.dimen.mr_controller_volume_group_list_item_height); 474692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupListMaxHeight = res.getDimensionPixelSize( 475692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim R.dimen.mr_controller_volume_group_list_max_height); 476692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 477692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Fetch art icons again for layout changes to resize it accordingly 478692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtIconBitmap = null; 479692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtIconUri = null; 480692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim updateArtIconIfNeeded(); 481692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim update(false); 482692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 483692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 484692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 485692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onAttachedToWindow() { 486692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim super.onAttachedToWindow(); 487692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mAttachedToWindow = true; 488692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 489692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRouter.addCallback(MediaRouteSelector.EMPTY, mCallback, 490692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouter.CALLBACK_FLAG_UNFILTERED_EVENTS); 491692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim setMediaSession(mRouter.getMediaSessionToken()); 492692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 493692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 494692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 495692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onDetachedFromWindow() { 496692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRouter.removeCallback(mCallback); 497692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim setMediaSession(null); 498692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mAttachedToWindow = false; 499692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim super.onDetachedFromWindow(); 500692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 501692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 502692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 503692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public boolean onKeyDown(int keyCode, KeyEvent event) { 504692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 505692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 506692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRoute.requestUpdateVolume(keyCode == KeyEvent.KEYCODE_VOLUME_DOWN ? -1 : 1); 507692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return true; 508692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 509692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return super.onKeyDown(keyCode, event); 510692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 511692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 512692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 513692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public boolean onKeyUp(int keyCode, KeyEvent event) { 514692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN 515692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim || keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 516692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return true; 517692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 518692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return super.onKeyUp(keyCode, event); 519692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 520692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 521692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim void update(boolean animate) { 522692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Defer dialog updates if a user is adjusting a volume in the list 523692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mRouteInVolumeSliderTouched != null) { 524692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mHasPendingUpdate = true; 525692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mPendingUpdateAnimationNeeded |= animate; 526692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return; 527692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 528692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mHasPendingUpdate = false; 529692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mPendingUpdateAnimationNeeded = false; 530692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (!mRoute.isSelected() || mRoute.isDefaultOrBluetooth()) { 531692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim dismiss(); 532692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return; 533692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 534692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (!mCreated) { 535692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return; 536692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 537692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 538692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRouteNameTextView.setText(mRoute.getName()); 539692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mDisconnectButton.setVisibility(mRoute.canDisconnect() ? View.VISIBLE : View.GONE); 540692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mCustomControlView == null && mArtIconIsLoaded) { 541692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (isBitmapRecycled(mArtIconLoadedBitmap)) { 542692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Log.w(TAG, "Can't set artwork image with recycled bitmap: " + mArtIconLoadedBitmap); 543692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 544692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtView.setImageBitmap(mArtIconLoadedBitmap); 545692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtView.setBackgroundColor(mArtIconBackgroundColor); 546692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 547692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim clearLoadedBitmap(); 548692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 549692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim updateVolumeControlLayout(); 550692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim updatePlaybackControlLayout(); 551692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim updateLayoutHeight(animate); 552692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 553692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 554692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private boolean isBitmapRecycled(Bitmap bitmap) { 555692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return bitmap != null && bitmap.isRecycled(); 556692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 557692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 558692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private boolean canShowPlaybackControlLayout() { 559692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return mCustomControlView == null && (mDescription != null || mState != null); 560692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 561692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 562692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 563692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Returns the height of main media controller which includes playback control and master 564692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * volume control. 565692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 566692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private int getMainControllerHeight(boolean showPlaybackControl) { 567692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int height = 0; 568692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (showPlaybackControl || mVolumeControlLayout.getVisibility() == View.VISIBLE) { 569692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim height += mMediaMainControlLayout.getPaddingTop() 570692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim + mMediaMainControlLayout.getPaddingBottom(); 571692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (showPlaybackControl) { 572692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim height += mPlaybackControlLayout.getMeasuredHeight(); 573692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 574692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mVolumeControlLayout.getVisibility() == View.VISIBLE) { 575692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim height += mVolumeControlLayout.getMeasuredHeight(); 576692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 577692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (showPlaybackControl && mVolumeControlLayout.getVisibility() == View.VISIBLE) { 578692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim height += mDividerView.getMeasuredHeight(); 579692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 580692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 581692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return height; 582692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 583692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 584692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private void updateMediaControlVisibility(boolean canShowPlaybackControlLayout) { 585692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // TODO: Update the top and bottom padding of the control layout according to the display 586692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // height. 587692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mDividerView.setVisibility((mVolumeControlLayout.getVisibility() == View.VISIBLE 588692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim && canShowPlaybackControlLayout) ? View.VISIBLE : View.GONE); 589692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mMediaMainControlLayout.setVisibility((mVolumeControlLayout.getVisibility() == View.GONE 590692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim && !canShowPlaybackControlLayout) ? View.GONE : View.VISIBLE); 591692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 592692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 593692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim void updateLayoutHeight(final boolean animate) { 594692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // We need to defer the update until the first layout has occurred, as we don't yet know the 595692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // overall visible display size in which the window this view is attached to has been 596692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // positioned in. 597692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mDefaultControlLayout.requestLayout(); 598692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ViewTreeObserver observer = mDefaultControlLayout.getViewTreeObserver(); 599692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 600692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 601692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onGlobalLayout() { 602692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mDefaultControlLayout.getViewTreeObserver().removeGlobalOnLayoutListener(this); 603692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mIsGroupListAnimating) { 604692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mIsGroupListAnimationPending = true; 605692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 606692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim updateLayoutHeightInternal(animate); 607692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 608692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 609692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim }); 610692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 611692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 612692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 613692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Updates the height of views and hide artwork or metadata if space is limited. 614692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 615692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim void updateLayoutHeightInternal(boolean animate) { 616692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Measure the size of widgets and get the height of main components. 617692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int oldHeight = getLayoutHeight(mMediaMainControlLayout); 618692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim setLayoutHeight(mMediaMainControlLayout, ViewGroup.LayoutParams.MATCH_PARENT); 619692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim updateMediaControlVisibility(canShowPlaybackControlLayout()); 620692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim View decorView = getWindow().getDecorView(); 621692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim decorView.measure( 622692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MeasureSpec.makeMeasureSpec(getWindow().getAttributes().width, MeasureSpec.EXACTLY), 623692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MeasureSpec.UNSPECIFIED); 624692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim setLayoutHeight(mMediaMainControlLayout, oldHeight); 625692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int artViewHeight = 0; 626692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mCustomControlView == null && mArtView.getDrawable() instanceof BitmapDrawable) { 627692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Bitmap art = ((BitmapDrawable) mArtView.getDrawable()).getBitmap(); 628692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (art != null) { 629692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim artViewHeight = getDesiredArtHeight(art.getWidth(), art.getHeight()); 630692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtView.setScaleType(art.getWidth() >= art.getHeight() 631692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ? ImageView.ScaleType.FIT_XY : ImageView.ScaleType.FIT_CENTER); 632692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 633692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 634692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int mainControllerHeight = getMainControllerHeight(canShowPlaybackControlLayout()); 635692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int volumeGroupListCount = mGroupMemberRoutes.size(); 636692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Scale down volume group list items in landscape mode. 637692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int expandedGroupListHeight = getGroup() == null ? 0 : 638692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupListItemHeight * getGroup().getRoutes().size(); 639692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (volumeGroupListCount > 0) { 640692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim expandedGroupListHeight += mVolumeGroupListPaddingTop; 641692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 642692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim expandedGroupListHeight = Math.min(expandedGroupListHeight, mVolumeGroupListMaxHeight); 643692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int visibleGroupListHeight = mIsGroupExpanded ? expandedGroupListHeight : 0; 644692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 645692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int desiredControlLayoutHeight = 646692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Math.max(artViewHeight, visibleGroupListHeight) + mainControllerHeight; 647692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Rect visibleRect = new Rect(); 648692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim decorView.getWindowVisibleDisplayFrame(visibleRect); 649692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Height of non-control views in decor view. 650692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // This includes title bar, button bar, and dialog's vertical padding which should be 651692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // always shown. 652692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int nonControlViewHeight = mDialogAreaLayout.getMeasuredHeight() 653692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim - mDefaultControlLayout.getMeasuredHeight(); 654692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Maximum allowed height for controls to fit screen. 655692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int maximumControlViewHeight = visibleRect.height() - nonControlViewHeight; 656692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 657692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Show artwork if it fits the screen. 658692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mCustomControlView == null && artViewHeight > 0 659692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim && desiredControlLayoutHeight <= maximumControlViewHeight) { 660692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtView.setVisibility(View.VISIBLE); 661692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim setLayoutHeight(mArtView, artViewHeight); 662692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 663692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (getLayoutHeight(mVolumeGroupList) + mMediaMainControlLayout.getMeasuredHeight() 664692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim >= mDefaultControlLayout.getMeasuredHeight()) { 665692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtView.setVisibility(View.GONE); 666692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 667692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim artViewHeight = 0; 668692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim desiredControlLayoutHeight = visibleGroupListHeight + mainControllerHeight; 669692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 670692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Show the playback control if it fits the screen. 671692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (canShowPlaybackControlLayout() 672692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim && desiredControlLayoutHeight <= maximumControlViewHeight) { 673692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mPlaybackControlLayout.setVisibility(View.VISIBLE); 674692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 675692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mPlaybackControlLayout.setVisibility(View.GONE); 676692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 677692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim updateMediaControlVisibility(mPlaybackControlLayout.getVisibility() == View.VISIBLE); 678692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mainControllerHeight = getMainControllerHeight( 679692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mPlaybackControlLayout.getVisibility() == View.VISIBLE); 680692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim desiredControlLayoutHeight = 681692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Math.max(artViewHeight, visibleGroupListHeight) + mainControllerHeight; 682692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 683692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Limit the volume group list height to fit the screen. 684692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (desiredControlLayoutHeight > maximumControlViewHeight) { 685692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim visibleGroupListHeight -= (desiredControlLayoutHeight - maximumControlViewHeight); 686692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim desiredControlLayoutHeight = maximumControlViewHeight; 687692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 688692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Update the layouts with the computed heights. 689692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mMediaMainControlLayout.clearAnimation(); 690692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupList.clearAnimation(); 691692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mDefaultControlLayout.clearAnimation(); 692692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (animate) { 693692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim animateLayoutHeight(mMediaMainControlLayout, mainControllerHeight); 694692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim animateLayoutHeight(mVolumeGroupList, visibleGroupListHeight); 695692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim animateLayoutHeight(mDefaultControlLayout, desiredControlLayoutHeight); 696692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 697692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim setLayoutHeight(mMediaMainControlLayout, mainControllerHeight); 698692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim setLayoutHeight(mVolumeGroupList, visibleGroupListHeight); 699692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim setLayoutHeight(mDefaultControlLayout, desiredControlLayoutHeight); 700692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 701692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Maximize the window size with a transparent layout in advance for smooth animation. 702692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim setLayoutHeight(mExpandableAreaLayout, visibleRect.height()); 703692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim rebuildVolumeGroupList(animate); 704692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 705692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 706692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim void updateVolumeGroupItemHeight(View item) { 707692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim LinearLayout container = (LinearLayout) item.findViewById(R.id.volume_item_container); 708692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim setLayoutHeight(container, mVolumeGroupListItemHeight); 709692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim View icon = item.findViewById(R.id.mr_volume_item_icon); 710692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ViewGroup.LayoutParams lp = icon.getLayoutParams(); 711692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim lp.width = mVolumeGroupListItemIconSize; 712692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim lp.height = mVolumeGroupListItemIconSize; 713692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim icon.setLayoutParams(lp); 714692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 715692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 716692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private void animateLayoutHeight(final View view, int targetHeight) { 717692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim final int startValue = getLayoutHeight(view); 718692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim final int endValue = targetHeight; 719692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Animation anim = new Animation() { 720692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 721692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim protected void applyTransformation(float interpolatedTime, Transformation t) { 722692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int height = startValue - (int) ((startValue - endValue) * interpolatedTime); 723692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim setLayoutHeight(view, height); 724692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 725692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim }; 726692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim anim.setDuration(mGroupListAnimationDurationMs); 727692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (android.os.Build.VERSION.SDK_INT >= 21) { 728692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim anim.setInterpolator(mInterpolator); 729692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 730692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim view.startAnimation(anim); 731692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 732692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 733692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim void loadInterpolator() { 734d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim mInterpolator = 735d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim mIsGroupExpanded ? mLinearOutSlowInInterpolator : mFastOutSlowInInterpolator; 736692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 737692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 738692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private void updateVolumeControlLayout() { 739692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (isVolumeControlAvailable(mRoute)) { 740692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mVolumeControlLayout.getVisibility() == View.GONE) { 741692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeControlLayout.setVisibility(View.VISIBLE); 742692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeSlider.setMax(mRoute.getVolumeMax()); 743692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeSlider.setProgress(mRoute.getVolume()); 744692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupExpandCollapseButton.setVisibility(getGroup() == null ? View.GONE 745692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim : View.VISIBLE); 746692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 747692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 748692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeControlLayout.setVisibility(View.GONE); 749692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 750692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 751692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 752692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private void rebuildVolumeGroupList(boolean animate) { 753692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim List<MediaRouter.RouteInfo> routes = getGroup() == null ? null : getGroup().getRoutes(); 754692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (routes == null) { 755692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupMemberRoutes.clear(); 756692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupAdapter.notifyDataSetChanged(); 757692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else if (MediaRouteDialogHelper.listUnorderedEquals(mGroupMemberRoutes, routes)) { 758692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupAdapter.notifyDataSetChanged(); 759692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 760692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim HashMap<MediaRouter.RouteInfo, Rect> previousRouteBoundMap = animate 761692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ? MediaRouteDialogHelper.getItemBoundMap(mVolumeGroupList, mVolumeGroupAdapter) 762692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim : null; 763692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim HashMap<MediaRouter.RouteInfo, BitmapDrawable> previousRouteBitmapMap = animate 764692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ? MediaRouteDialogHelper.getItemBitmapMap(mContext, mVolumeGroupList, 765692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupAdapter) : null; 766692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupMemberRoutesAdded = 767692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouteDialogHelper.getItemsAdded(mGroupMemberRoutes, routes); 768692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupMemberRoutesRemoved = MediaRouteDialogHelper.getItemsRemoved(mGroupMemberRoutes, 769692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim routes); 770692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupMemberRoutes.addAll(0, mGroupMemberRoutesAdded); 771692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupMemberRoutes.removeAll(mGroupMemberRoutesRemoved); 772692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupAdapter.notifyDataSetChanged(); 773692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (animate && mIsGroupExpanded 774692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim && mGroupMemberRoutesAdded.size() + mGroupMemberRoutesRemoved.size() > 0) { 775692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim animateGroupListItems(previousRouteBoundMap, previousRouteBitmapMap); 776692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 777692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupMemberRoutesAdded = null; 778692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupMemberRoutesRemoved = null; 779692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 780692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 781692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 782692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 783692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private void animateGroupListItems(final Map<MediaRouter.RouteInfo, Rect> previousRouteBoundMap, 784692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim final Map<MediaRouter.RouteInfo, BitmapDrawable> previousRouteBitmapMap) { 785692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupList.setEnabled(false); 786692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupList.requestLayout(); 787692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mIsGroupListAnimating = true; 788692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ViewTreeObserver observer = mVolumeGroupList.getViewTreeObserver(); 789692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 790692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 791692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onGlobalLayout() { 792692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupList.getViewTreeObserver().removeGlobalOnLayoutListener(this); 793692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim animateGroupListItemsInternal(previousRouteBoundMap, previousRouteBitmapMap); 794692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 795692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim }); 796692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 797692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 798692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim void animateGroupListItemsInternal( 799692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Map<MediaRouter.RouteInfo, Rect> previousRouteBoundMap, 800692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Map<MediaRouter.RouteInfo, BitmapDrawable> previousRouteBitmapMap) { 801692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mGroupMemberRoutesAdded == null || mGroupMemberRoutesRemoved == null) { 802692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return; 803692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 804692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int groupSizeDelta = mGroupMemberRoutesAdded.size() - mGroupMemberRoutesRemoved.size(); 805692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean listenerRegistered = false; 806692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Animation.AnimationListener listener = new Animation.AnimationListener() { 807692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 808692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onAnimationStart(Animation animation) { 809692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupList.startAnimationAll(); 810692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupList.postDelayed(mGroupListFadeInAnimation, 811692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupListAnimationDurationMs); 812692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 813692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 814692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 815692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onAnimationEnd(Animation animation) { } 816692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 817692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 818692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onAnimationRepeat(Animation animation) { } 819692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim }; 820692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 821692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Animate visible items from previous positions to current positions except routes added 822692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // just before. Added routes will remain hidden until translate animation finishes. 823692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int first = mVolumeGroupList.getFirstVisiblePosition(); 824692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim for (int i = 0; i < mVolumeGroupList.getChildCount(); ++i) { 825692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim View view = mVolumeGroupList.getChildAt(i); 826692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int position = first + i; 827692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouter.RouteInfo route = mVolumeGroupAdapter.getItem(position); 828692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Rect previousBounds = previousRouteBoundMap.get(route); 829692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int currentTop = view.getTop(); 830692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int previousTop = previousBounds != null ? previousBounds.top 831692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim : (currentTop + mVolumeGroupListItemHeight * groupSizeDelta); 832692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim AnimationSet animSet = new AnimationSet(true); 833692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mGroupMemberRoutesAdded != null && mGroupMemberRoutesAdded.contains(route)) { 834692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim previousTop = currentTop; 835692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Animation alphaAnim = new AlphaAnimation(0.0f, 0.0f); 836692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim alphaAnim.setDuration(mGroupListFadeInDurationMs); 837692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim animSet.addAnimation(alphaAnim); 838692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 839692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Animation translationAnim = new TranslateAnimation(0, 0, previousTop - currentTop, 0); 840692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim translationAnim.setDuration(mGroupListAnimationDurationMs); 841692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim animSet.addAnimation(translationAnim); 842692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim animSet.setFillAfter(true); 843692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim animSet.setFillEnabled(true); 844692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim animSet.setInterpolator(mInterpolator); 845692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (!listenerRegistered) { 846692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim listenerRegistered = true; 847692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim animSet.setAnimationListener(listener); 848692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 849692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim view.clearAnimation(); 850692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim view.startAnimation(animSet); 851692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim previousRouteBoundMap.remove(route); 852692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim previousRouteBitmapMap.remove(route); 853692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 854692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 855692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // If a member route doesn't exist any longer, it can be either removed or moved out of the 856692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // ListView layout boundary. In this case, use the previously captured bitmaps for 857692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // animation. 858692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim for (Map.Entry<MediaRouter.RouteInfo, BitmapDrawable> item 859692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim : previousRouteBitmapMap.entrySet()) { 860692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim final MediaRouter.RouteInfo route = item.getKey(); 861692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim final BitmapDrawable bitmap = item.getValue(); 862692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim final Rect bounds = previousRouteBoundMap.get(route); 863692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim OverlayObject object = null; 864692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mGroupMemberRoutesRemoved.contains(route)) { 865692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim object = new OverlayObject(bitmap, bounds).setAlphaAnimation(1.0f, 0.0f) 866692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim .setDuration(mGroupListFadeOutDurationMs) 867692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim .setInterpolator(mInterpolator); 868692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 869692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int deltaY = groupSizeDelta * mVolumeGroupListItemHeight; 870692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim object = new OverlayObject(bitmap, bounds).setTranslateYAnimation(deltaY) 871692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim .setDuration(mGroupListAnimationDurationMs) 872692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim .setInterpolator(mInterpolator) 873692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim .setAnimationEndListener(new OverlayObject.OnAnimationEndListener() { 874692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 875692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onAnimationEnd() { 876692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupMemberRoutesAnimatingWithBitmap.remove(route); 877692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupAdapter.notifyDataSetChanged(); 878692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 879692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim }); 880692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupMemberRoutesAnimatingWithBitmap.add(route); 881692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 882692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupList.addOverlayObject(object); 883692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 884692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 885692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 886692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim void startGroupListFadeInAnimation() { 887692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim clearGroupListAnimation(true); 888692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupList.requestLayout(); 889692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ViewTreeObserver observer = mVolumeGroupList.getViewTreeObserver(); 890692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim observer.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() { 891692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 892692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onGlobalLayout() { 893692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupList.getViewTreeObserver().removeGlobalOnLayoutListener(this); 894692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim startGroupListFadeInAnimationInternal(); 895692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 896692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim }); 897692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 898692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 899692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim void startGroupListFadeInAnimationInternal() { 900692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mGroupMemberRoutesAdded != null && mGroupMemberRoutesAdded.size() != 0) { 901692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim fadeInAddedRoutes(); 902692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 903692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim finishAnimation(true); 904692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 905692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 906692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 907692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim void finishAnimation(boolean animate) { 908692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupMemberRoutesAdded = null; 909692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mGroupMemberRoutesRemoved = null; 910692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mIsGroupListAnimating = false; 911692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mIsGroupListAnimationPending) { 912692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mIsGroupListAnimationPending = false; 913692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim updateLayoutHeight(animate); 914692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 915692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupList.setEnabled(true); 916692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 917692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 918692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private void fadeInAddedRoutes() { 919692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Animation.AnimationListener listener = new Animation.AnimationListener() { 920692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 921692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onAnimationStart(Animation animation) { } 922692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 923692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 924692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onAnimationEnd(Animation animation) { 925692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim finishAnimation(true); 926692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 927692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 928692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 929692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onAnimationRepeat(Animation animation) { } 930692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim }; 931692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean listenerRegistered = false; 932692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int first = mVolumeGroupList.getFirstVisiblePosition(); 933692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim for (int i = 0; i < mVolumeGroupList.getChildCount(); ++i) { 934692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim View view = mVolumeGroupList.getChildAt(i); 935692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int position = first + i; 936692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouter.RouteInfo route = mVolumeGroupAdapter.getItem(position); 937692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mGroupMemberRoutesAdded.contains(route)) { 938692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Animation alphaAnim = new AlphaAnimation(0.0f, 1.0f); 939692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim alphaAnim.setDuration(mGroupListFadeInDurationMs); 940692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim alphaAnim.setFillEnabled(true); 941692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim alphaAnim.setFillAfter(true); 942692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (!listenerRegistered) { 943692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim listenerRegistered = true; 944692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim alphaAnim.setAnimationListener(listener); 945692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 946692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim view.clearAnimation(); 947692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim view.startAnimation(alphaAnim); 948692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 949692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 950692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 951692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 952692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim void clearGroupListAnimation(boolean exceptAddedRoutes) { 953692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int first = mVolumeGroupList.getFirstVisiblePosition(); 954692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim for (int i = 0; i < mVolumeGroupList.getChildCount(); ++i) { 955692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim View view = mVolumeGroupList.getChildAt(i); 956692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int position = first + i; 957692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouter.RouteInfo route = mVolumeGroupAdapter.getItem(position); 958692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (exceptAddedRoutes && mGroupMemberRoutesAdded != null 959692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim && mGroupMemberRoutesAdded.contains(route)) { 960692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim continue; 961692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 962692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim LinearLayout container = (LinearLayout) view.findViewById(R.id.volume_item_container); 963692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim container.setVisibility(View.VISIBLE); 964692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim AnimationSet animSet = new AnimationSet(true); 965692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Animation alphaAnim = new AlphaAnimation(1.0f, 1.0f); 966692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim alphaAnim.setDuration(0); 967692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim animSet.addAnimation(alphaAnim); 968692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Animation translationAnim = new TranslateAnimation(0, 0, 0, 0); 969692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim translationAnim.setDuration(0); 970692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim animSet.setFillAfter(true); 971692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim animSet.setFillEnabled(true); 972692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim view.clearAnimation(); 973692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim view.startAnimation(animSet); 974692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 975692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeGroupList.stopAnimationAll(); 976692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (!exceptAddedRoutes) { 977692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim finishAnimation(false); 978692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 979692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 980692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 981692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private void updatePlaybackControlLayout() { 982692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (canShowPlaybackControlLayout()) { 983692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim CharSequence title = mDescription == null ? null : mDescription.getTitle(); 984692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean hasTitle = !TextUtils.isEmpty(title); 985692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 986692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim CharSequence subtitle = mDescription == null ? null : mDescription.getSubtitle(); 987692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean hasSubtitle = !TextUtils.isEmpty(subtitle); 988692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 989692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean showTitle = false; 990692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean showSubtitle = false; 991692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mRoute.getPresentationDisplayId() 992692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim != MediaRouter.RouteInfo.PRESENTATION_DISPLAY_ID_NONE) { 993692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // The user is currently casting screen. 994d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim mTitleView.setText(ApiHelper.getLibResources().getString( 995d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim R.string.mr_controller_casting_screen)); 996692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim showTitle = true; 997692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else if (mState == null || mState.getState() == PlaybackStateCompat.STATE_NONE) { 998692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Show "No media selected" as we don't yet know the playback state. 999d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim mTitleView.setText(ApiHelper.getLibResources().getString( 1000d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim R.string.mr_controller_no_media_selected)); 1001692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim showTitle = true; 1002692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else if (!hasTitle && !hasSubtitle) { 1003d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim mTitleView.setText(ApiHelper.getLibResources().getString( 1004d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim R.string.mr_controller_no_info_available)); 1005692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim showTitle = true; 1006692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 1007692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (hasTitle) { 1008692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mTitleView.setText(title); 1009692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim showTitle = true; 1010692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1011692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (hasSubtitle) { 1012692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mSubtitleView.setText(subtitle); 1013692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim showSubtitle = true; 1014692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1015692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1016692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mTitleView.setVisibility(showTitle ? View.VISIBLE : View.GONE); 1017692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mSubtitleView.setVisibility(showSubtitle ? View.VISIBLE : View.GONE); 1018692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1019692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mState != null) { 1020692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean isPlaying = mState.getState() == PlaybackStateCompat.STATE_BUFFERING 1021692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim || mState.getState() == PlaybackStateCompat.STATE_PLAYING; 1022692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Context playbackControlButtonContext = mPlaybackControlButton.getContext(); 1023692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean visible = true; 1024692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int iconDrawableAttr = 0; 1025692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int iconDescResId = 0; 1026692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (isPlaying && isPauseActionSupported()) { 1027692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim iconDrawableAttr = R.attr.mediaRoutePauseDrawable; 1028692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim iconDescResId = R.string.mr_controller_pause; 1029692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else if (isPlaying && isStopActionSupported()) { 1030692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim iconDrawableAttr = R.attr.mediaRouteStopDrawable; 1031692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim iconDescResId = R.string.mr_controller_stop; 1032692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else if (!isPlaying && isPlayActionSupported()) { 1033692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim iconDrawableAttr = R.attr.mediaRoutePlayDrawable; 1034692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim iconDescResId = R.string.mr_controller_play; 1035692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 1036692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim visible = false; 1037692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1038692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mPlaybackControlButton.setVisibility(visible ? View.VISIBLE : View.GONE); 1039692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (visible) { 1040692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mPlaybackControlButton.setImageResource( 1041692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouterThemeHelper.getThemeResource( 1042692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim playbackControlButtonContext, iconDrawableAttr)); 1043692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mPlaybackControlButton.setContentDescription( 1044692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim playbackControlButtonContext.getResources() 1045692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim .getText(iconDescResId)); 1046692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1047692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1048692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1049692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1050692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1051692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private boolean isPlayActionSupported() { 1052692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return (mState.getActions() & (ACTION_PLAY | ACTION_PLAY_PAUSE)) != 0; 1053692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1054692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1055692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private boolean isPauseActionSupported() { 1056692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return (mState.getActions() & (ACTION_PAUSE | ACTION_PLAY_PAUSE)) != 0; 1057692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1058692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1059692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private boolean isStopActionSupported() { 1060692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return (mState.getActions() & ACTION_STOP) != 0; 1061692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1062692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1063692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean isVolumeControlAvailable(MediaRouter.RouteInfo route) { 1064692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return mVolumeControlEnabled && route.getVolumeHandling() 1065692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim == MediaRouter.RouteInfo.PLAYBACK_VOLUME_VARIABLE; 1066692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1067692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1068692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private static int getLayoutHeight(View view) { 1069692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return view.getLayoutParams().height; 1070692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1071692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1072692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim static void setLayoutHeight(View view, int height) { 1073692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ViewGroup.LayoutParams lp = view.getLayoutParams(); 1074692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim lp.height = height; 1075692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim view.setLayoutParams(lp); 1076692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1077692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1078692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private static boolean uriEquals(Uri uri1, Uri uri2) { 1079692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (uri1 != null && uri1.equals(uri2)) { 1080692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return true; 1081692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else if (uri1 == null && uri2 == null) { 1082692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return true; 1083692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1084692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return false; 1085692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1086692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1087692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 1088692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Returns desired art height to fit into controller dialog. 1089692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 1090692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int getDesiredArtHeight(int originalWidth, int originalHeight) { 1091692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (originalWidth >= originalHeight) { 1092692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // For landscape art, fit width to dialog width. 1093692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return (int) ((float) mDialogContentWidth * originalHeight / originalWidth + 0.5f); 1094692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1095692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // For portrait art, fit height to 16:9 ratio case's height. 1096692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return (int) ((float) mDialogContentWidth * 9 / 16 + 0.5f); 1097692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1098692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1099692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim void updateArtIconIfNeeded() { 1100692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mCustomControlView != null || !isIconChanged()) { 1101692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return; 1102692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1103692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mFetchArtTask != null) { 1104692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mFetchArtTask.cancel(true); 1105692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1106692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mFetchArtTask = new FetchArtTask(); 1107692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mFetchArtTask.execute(); 1108692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1109692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1110692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 1111692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Clear the bitmap loaded by FetchArtTask. Will be called after the loaded bitmaps are applied 1112692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * to artwork, or no longer valid. 1113692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 1114692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim void clearLoadedBitmap() { 1115692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtIconIsLoaded = false; 1116692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtIconLoadedBitmap = null; 1117692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtIconBackgroundColor = 0; 1118692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1119692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1120692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim /** 1121692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Returns whether a new art image is different from an original art image. Compares 1122692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * Bitmap objects first, and then compares URIs only if bitmap is unchanged with 1123692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim * a null value. 1124692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim */ 1125692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private boolean isIconChanged() { 1126692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Bitmap newBitmap = mDescription == null ? null : mDescription.getIconBitmap(); 1127692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Uri newUri = mDescription == null ? null : mDescription.getIconUri(); 1128692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Bitmap oldBitmap = mFetchArtTask == null ? mArtIconBitmap : mFetchArtTask.getIconBitmap(); 1129692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Uri oldUri = mFetchArtTask == null ? mArtIconUri : mFetchArtTask.getIconUri(); 1130692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (oldBitmap != newBitmap) { 1131692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return true; 1132692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else if (oldBitmap == null && !uriEquals(oldUri, newUri)) { 1133692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return true; 1134692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1135692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return false; 1136692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1137692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1138692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private final class MediaRouterCallback extends MediaRouter.Callback { 1139692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouterCallback() { 1140692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1141692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1142692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 1143692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route) { 1144692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim update(false); 1145692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1146692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1147692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 1148692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onRouteChanged(MediaRouter router, MediaRouter.RouteInfo route) { 1149692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim update(true); 1150692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1151692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1152692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 1153692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onRouteVolumeChanged(MediaRouter router, MediaRouter.RouteInfo route) { 1154692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim SeekBar volumeSlider = mVolumeSliderMap.get(route); 1155692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int volume = route.getVolume(); 1156692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (DEBUG) { 1157692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Log.d(TAG, "onRouteVolumeChanged(), route.getVolume:" + volume); 1158692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1159692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (volumeSlider != null && mRouteInVolumeSliderTouched != route) { 1160692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim volumeSlider.setProgress(volume); 1161692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1162692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1163692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1164692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1165692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private final class MediaControllerCallback extends MediaControllerCompat.Callback { 1166692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaControllerCallback() { 1167692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1168692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1169692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 1170692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onSessionDestroyed() { 1171692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mMediaController != null) { 1172692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mMediaController.unregisterCallback(mControllerCallback); 1173692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mMediaController = null; 1174692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1175692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1176692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1177692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 1178692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onPlaybackStateChanged(PlaybackStateCompat state) { 1179692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mState = state; 1180692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim update(false); 1181692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1182692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1183692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 1184692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onMetadataChanged(MediaMetadataCompat metadata) { 1185692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mDescription = metadata == null ? null : metadata.getDescription(); 1186692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim updateArtIconIfNeeded(); 1187692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim update(false); 1188692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1189692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1190692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1191692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private final class ClickListener implements View.OnClickListener { 1192692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ClickListener() { 1193692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1194692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1195692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 1196692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onClick(View v) { 1197692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int id = v.getId(); 1198692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (id == BUTTON_STOP_RES_ID || id == BUTTON_DISCONNECT_RES_ID) { 1199692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mRoute.isSelected()) { 1200692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRouter.unselect(id == BUTTON_STOP_RES_ID ? 1201692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouter.UNSELECT_REASON_STOPPED : 1202692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouter.UNSELECT_REASON_DISCONNECTED); 1203692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1204692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim dismiss(); 1205692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else if (id == R.id.mr_control_playback_ctrl) { 1206692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mMediaController != null && mState != null) { 1207692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean isPlaying = mState.getState() == PlaybackStateCompat.STATE_PLAYING; 1208692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int actionDescResId = 0; 1209692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (isPlaying && isPauseActionSupported()) { 1210692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mMediaController.getTransportControls().pause(); 1211692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim actionDescResId = R.string.mr_controller_pause; 1212692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else if (isPlaying && isStopActionSupported()) { 1213692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mMediaController.getTransportControls().stop(); 1214692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim actionDescResId = R.string.mr_controller_stop; 1215692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else if (!isPlaying && isPlayActionSupported()){ 1216692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mMediaController.getTransportControls().play(); 1217692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim actionDescResId = R.string.mr_controller_play; 1218692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1219692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Announce the action for accessibility. 1220692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mAccessibilityManager != null && mAccessibilityManager.isEnabled() 1221692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim && actionDescResId != 0) { 1222692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim AccessibilityEvent event = AccessibilityEvent.obtain( 1223692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim AccessibilityEventCompat.TYPE_ANNOUNCEMENT); 1224692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim event.setPackageName(mContext.getPackageName()); 1225692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim event.setClassName(getClass().getName()); 1226d5b1f00dbd91f5bc64f30891ec7a35f28274dbb0Sungsoo Lim event.getText().add(ApiHelper.getLibResources().getString(actionDescResId)); 1227692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mAccessibilityManager.sendAccessibilityEvent(event); 1228692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1229692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1230692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else if (id == R.id.mr_close) { 1231692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim dismiss(); 1232692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1233692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1234692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1235692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1236692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private class VolumeChangeListener implements SeekBar.OnSeekBarChangeListener { 1237692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private final Runnable mStopTrackingTouch = new Runnable() { 1238692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 1239692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void run() { 1240692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mRouteInVolumeSliderTouched != null) { 1241692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRouteInVolumeSliderTouched = null; 1242692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mHasPendingUpdate) { 1243692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim update(mPendingUpdateAnimationNeeded); 1244692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1245692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1246692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1247692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim }; 1248692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1249692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim VolumeChangeListener() { 1250692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1251692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1252692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 1253692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onStartTrackingTouch(SeekBar seekBar) { 1254692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mRouteInVolumeSliderTouched != null) { 1255692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeSlider.removeCallbacks(mStopTrackingTouch); 1256692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1257692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mRouteInVolumeSliderTouched = (MediaRouter.RouteInfo) seekBar.getTag(); 1258692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1259692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1260692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 1261692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onStopTrackingTouch(SeekBar seekBar) { 1262692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Defer resetting mVolumeSliderTouched to allow the media route provider 1263692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // a little time to settle into its new state and publish the final 1264692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // volume update. 1265692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeSlider.postDelayed(mStopTrackingTouch, VOLUME_UPDATE_DELAY_MILLIS); 1266692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1267692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1268692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 1269692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 1270692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (fromUser) { 1271692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouter.RouteInfo route = (MediaRouter.RouteInfo) seekBar.getTag(); 1272692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (DEBUG) { 1273692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Log.d(TAG, "onProgressChanged(): calling " 1274692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim + "MediaRouter.RouteInfo.requestSetVolume(" + progress + ")"); 1275692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1276692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim route.requestSetVolume(progress); 1277692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1278692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1279692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1280692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1281692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private class VolumeGroupAdapter extends ArrayAdapter<MediaRouter.RouteInfo> { 1282692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim final float mDisabledAlpha; 1283692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1284692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public VolumeGroupAdapter(Context context, List<MediaRouter.RouteInfo> objects) { 1285692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim super(context, 0, objects); 1286692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mDisabledAlpha = MediaRouterThemeHelper.getDisabledAlpha(context); 1287692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1288692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1289692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 1290692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public boolean isEnabled(int position) { 1291692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return false; 1292692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1293692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1294692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 1295692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public View getView(final int position, View convertView, ViewGroup parent) { 1296692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim View v = convertView; 1297692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (v == null) { 1298692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim v = LayoutInflater.from(parent.getContext()).inflate( 1299692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim R.layout.mr_controller_volume_item, parent, false); 1300692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 1301692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim updateVolumeGroupItemHeight(v); 1302692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1303692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1304692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouter.RouteInfo route = getItem(position); 1305692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (route != null) { 1306692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim boolean isEnabled = route.isEnabled(); 1307692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1308692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim TextView routeName = (TextView) v.findViewById(R.id.mr_name); 1309692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim routeName.setEnabled(isEnabled); 1310692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim routeName.setText(route.getName()); 1311692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1312692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouteVolumeSlider volumeSlider = 1313692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim (MediaRouteVolumeSlider) v.findViewById(R.id.mr_volume_slider); 1314692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim MediaRouterThemeHelper.setVolumeSliderColor( 1315692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim parent.getContext(), volumeSlider, mVolumeGroupList); 1316692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim volumeSlider.setTag(route); 1317692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mVolumeSliderMap.put(route, volumeSlider); 1318692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim volumeSlider.setHideThumb(!isEnabled); 1319692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim volumeSlider.setEnabled(isEnabled); 1320692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (isEnabled) { 1321692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (isVolumeControlAvailable(route)) { 1322692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim volumeSlider.setMax(route.getVolumeMax()); 1323692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim volumeSlider.setProgress(route.getVolume()); 1324692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim volumeSlider.setOnSeekBarChangeListener(mVolumeChangeListener); 1325692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 1326692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim volumeSlider.setMax(100); 1327692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim volumeSlider.setProgress(100); 1328692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim volumeSlider.setEnabled(false); 1329692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1330692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1331692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1332692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ImageView volumeItemIcon = 1333692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim (ImageView) v.findViewById(R.id.mr_volume_item_icon); 1334692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim volumeItemIcon.setAlpha(isEnabled ? 0xFF : (int) (0xFF * mDisabledAlpha)); 1335692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1336692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // If overlay bitmap exists, real view should remain hidden until 1337692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // the animation ends. 1338692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim LinearLayout container = (LinearLayout) v.findViewById(R.id.volume_item_container); 1339692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim container.setVisibility(mGroupMemberRoutesAnimatingWithBitmap.contains(route) 1340692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ? View.INVISIBLE : View.VISIBLE); 1341692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1342692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Routes which are being added will be invisible until animation ends. 1343692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mGroupMemberRoutesAdded != null && mGroupMemberRoutesAdded.contains(route)) { 1344692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Animation alphaAnim = new AlphaAnimation(0.0f, 0.0f); 1345692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim alphaAnim.setDuration(0); 1346692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim alphaAnim.setFillEnabled(true); 1347692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim alphaAnim.setFillAfter(true); 1348692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim v.clearAnimation(); 1349692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim v.startAnimation(alphaAnim); 1350692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1351692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1352692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return v; 1353692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1354692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1355692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1356692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private class FetchArtTask extends AsyncTask<Void, Void, Bitmap> { 1357692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Show animation only when fetching takes a long time. 1358692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private static final long SHOW_ANIM_TIME_THRESHOLD_MILLIS = 120L; 1359692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1360692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private final Bitmap mIconBitmap; 1361692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private final Uri mIconUri; 1362692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private int mBackgroundColor; 1363692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private long mStartTimeMillis; 1364692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1365692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim FetchArtTask() { 1366692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Bitmap bitmap = mDescription == null ? null : mDescription.getIconBitmap(); 1367692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (isBitmapRecycled(bitmap)) { 1368692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Log.w(TAG, "Can't fetch the given art bitmap because it's already recycled."); 1369692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim bitmap = null; 1370692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1371692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mIconBitmap = bitmap; 1372692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mIconUri = mDescription == null ? null : mDescription.getIconUri(); 1373692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1374692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1375692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public Bitmap getIconBitmap() { 1376692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return mIconBitmap; 1377692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1378692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1379692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim public Uri getIconUri() { 1380692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return mIconUri; 1381692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1382692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1383692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 1384692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim protected void onPreExecute() { 1385692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mStartTimeMillis = SystemClock.uptimeMillis(); 1386692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim clearLoadedBitmap(); 1387692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1388692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1389692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 1390692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim protected Bitmap doInBackground(Void... arg) { 1391692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Bitmap art = null; 1392692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (mIconBitmap != null) { 1393692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim art = mIconBitmap; 1394692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else if (mIconUri != null) { 1395692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim InputStream stream = null; 1396692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim try { 1397692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if ((stream = openInputStreamByScheme(mIconUri)) == null) { 1398692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Log.w(TAG, "Unable to open: " + mIconUri); 1399692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return null; 1400692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1401692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Query art size. 1402692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim BitmapFactory.Options options = new BitmapFactory.Options(); 1403692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim options.inJustDecodeBounds = true; 1404692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim BitmapFactory.decodeStream(stream, null, options); 1405692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (options.outWidth == 0 || options.outHeight == 0) { 1406692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return null; 1407692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1408692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Rewind the stream in order to restart art decoding. 1409692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim try { 1410692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim stream.reset(); 1411692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } catch (IOException e) { 1412692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Failed to rewind the stream, try to reopen it. 1413692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim stream.close(); 1414692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if ((stream = openInputStreamByScheme(mIconUri)) == null) { 1415692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Log.w(TAG, "Unable to open: " + mIconUri); 1416692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return null; 1417692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1418692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1419692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Calculate required size to decode the art and possibly resize it. 1420692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim options.inJustDecodeBounds = false; 1421692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int reqHeight = getDesiredArtHeight(options.outWidth, options.outHeight); 1422692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim int ratio = options.outHeight / reqHeight; 1423692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim options.inSampleSize = Math.max(1, Integer.highestOneBit(ratio)); 1424692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (isCancelled()) { 1425692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return null; 1426692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1427692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim art = BitmapFactory.decodeStream(stream, null, options); 1428692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } catch (IOException e){ 1429692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Log.w(TAG, "Unable to open: " + mIconUri, e); 1430692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } finally { 1431692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (stream != null) { 1432692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim try { 1433692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim stream.close(); 1434692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } catch (IOException e) { 1435692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1436692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1437692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1438692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1439692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (isBitmapRecycled(art)) { 1440692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Log.w(TAG, "Can't use recycled bitmap: " + art); 1441692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return null; 1442692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1443692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (art != null && art.getWidth() < art.getHeight()) { 1444692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Portrait art requires dominant color as background color. 1445692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim Palette palette = new Palette.Builder(art).maximumColorCount(1).generate(); 1446692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mBackgroundColor = palette.getSwatches().isEmpty() 1447692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim ? 0 : palette.getSwatches().get(0).getRgb(); 1448692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1449692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return art; 1450692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1451692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1452692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim @Override 1453692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim protected void onPostExecute(Bitmap art) { 1454692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mFetchArtTask = null; 1455692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (!ObjectsCompat.equals(mArtIconBitmap, mIconBitmap) 1456692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim || !ObjectsCompat.equals(mArtIconUri, mIconUri)) { 1457692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtIconBitmap = mIconBitmap; 1458692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtIconLoadedBitmap = art; 1459692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtIconUri = mIconUri; 1460692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtIconBackgroundColor = mBackgroundColor; 1461692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim mArtIconIsLoaded = true; 1462692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim long elapsedTimeMillis = SystemClock.uptimeMillis() - mStartTimeMillis; 1463692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim // Loaded bitmap will be applied on the next update 1464692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim update(elapsedTimeMillis > SHOW_ANIM_TIME_THRESHOLD_MILLIS); 1465692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1466692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1467692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim 1468692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim private InputStream openInputStreamByScheme(Uri uri) throws IOException { 1469692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim String scheme = uri.getScheme().toLowerCase(); 1470692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim InputStream stream = null; 1471692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim if (ContentResolver.SCHEME_ANDROID_RESOURCE.equals(scheme) 1472692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim || ContentResolver.SCHEME_CONTENT.equals(scheme) 1473692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim || ContentResolver.SCHEME_FILE.equals(scheme)) { 1474692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim stream = mContext.getContentResolver().openInputStream(uri); 1475692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } else { 1476692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim URL url = new URL(uri.toString()); 1477692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim URLConnection conn = url.openConnection(); 1478692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim conn.setConnectTimeout(CONNECTION_TIMEOUT_MILLIS); 1479692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim conn.setReadTimeout(CONNECTION_TIMEOUT_MILLIS); 1480692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim stream = conn.getInputStream(); 1481692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1482692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim return (stream == null) ? null : new BufferedInputStream(stream); 1483692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1484692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim } 1485692a547730bbc95ad277d5214ef3d786ce1e499fSungsoo Lim} 1486