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